[comp.sources.amiga] v02i010: dme - programmer's text editor V1.31, Part02/06

page@swan.ulowell.edu (Bob Page) (10/22/88)

Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
Posting-number: Volume 2, Issue 10
Archive-name: editors/dme131.2of6

# This is a shell archive.  Remove anything before this line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# This archive contains the following files:
#	./src/subs.c
#	./src/refs.c
#	./src/main.c
#	./src/rexx.c
#	./src/Makefile
#	./src/cmd2.c
#
if `test ! -d ./src`
then
  mkdir ./src
  echo "mkdir ./src"
fi
if `test ! -s ./src/subs.c`
then
echo "writing ./src/subs.c"
cat > ./src/subs.c << '\Rogue\Monster\'

/*
 *  SUBS.C
 *
 *	(C)Copyright 1987 by Matthew Dillon, All Rights Reserved
 *
 *  Subroutines.
 */

#include "defs.h"

/*
 *  Create DME's text icon.
 */

makemygadget(gad)
register struct Gadget *gad;
{
    static unsigned long ga[] = {
	0xFFFFFFFF,	/* 32 pixels across */
	0x80FDCBFD,
	0xFFFDDFFD,
	0x80000001,
	0x80DFDDDF,
	0x80000001,
	0xBC0EF00B,
	0x80000001,
	0xBFC00CDD,
	0x80000001,
	0xA00DF00F,
	0x80000001,
	0x80000001,

	0x80000001,
	0x80FDCBFD,
	0xFFFDDFFD,
	0x80000001,
	0x80DFDDDF,
	0x80000001,
	0xBC0EF00B,
	0x80000001,
	0xBFC00CDD,
	0x80000001,
	0xA00DF00F,
	0x80000001,
	0xFFFFFFFF
    };
    static struct Image image = {
	0, 0, 20, sizeof(ga)/4/2, 2, (unsigned short *)ga, 3, 0, NULL
    };
    bzero(gad, sizeof(struct Gadget));
    gad->Width = 20;
    gad->Height = sizeof(ga)/4/2 + 1;
    gad->Flags	= GADGIMAGE|GADGHCOMP;
    gad->GadgetType   = BOOLGADGET;
    gad->Activation = RELVERIFY|GADGIMMEDIATE;
    gad->GadgetRender = (APTR)&image;
}

/*
 * return index of first non space.  Returns 0 if no spaces found.
 */

firstns(str)
register char *str;
{
    register short i;

    for (i = 0; str[i] && str[i] == ' '; ++i);
    if (str[i] == 0)
	i = 0;
    return(i);
}

/*
 *  Return index of last non-space, 0 if no spaces.
 */

lastns(str)
register char *str;
{
    register short i;

    for (i = strlen(str) - 1; i > 0 && str[i] == ' '; --i);
    if (i < 0)
	i = 0;
    return(i);
}

/*
 *  Return length of word under cursor
 */

wordlen(str)
register char *str;
{
    register short i;

    for (i = 0; *str && *str != ' '; ++i, ++str);
    return(i);
}

/*
 *  Find the path from some root device to a specific filename (src), and
 *  stick the result in (dest).  If unable to backtrace along directories,
 *  simply copy (src) into (dest)
 *
 *  Returns (1) if able to backtrace, (0) if not.
 */

getpath(src, dest)
char *src, *dest;
{
    register long flock, pflock;
    register short len, total;
    register FIB *fib = (FIB *)malloc(sizeof(FIB));
    char c;

    dest[0] = 0;
    total = 1;
    flock = Lock(src, ACCESS_READ);
    if (flock == NULL) {                           /* missing file?    */
	for (len = strlen(src); len >= 0; --len) {
	    if (src[len] == '/') {
		--len;
		break;
	    }
	    if (src[len] == ':')
		break;
	}
	if (c = src[len + 1]) {
	    strcpy(dest, src+len+2);
	    total = strlen(dest)+1;
	}
	src[len + 1] = 0;
	flock = Lock(src, ACCESS_READ);
	src[len + 1] = c;
    }
    if (flock) {
	do {
	    pflock = ParentDir(flock);
	    if (Examine(flock, fib) == 0)
		fib->fib_FileName[0] = 0;
	    if (fib->fib_FileName[0] == 0)
		strcpy(fib->fib_FileName, "ram");
	    len = strlen(fib->fib_FileName);
	    bmov(dest, dest + len + 1, total);
	    dest[len] = (pflock) ? '/' : ':';
	    bmov(fib->fib_FileName, dest, len);
	    total += len + 1;
	    UnLock(flock);
	    flock = pflock;
	} while(pflock);
	len = strlen(dest) - 1;
	if (dest[len] == '/')
	    dest[len] = 0;
	return(1);
    }
    strcpy(dest, src);
    return(0);
}

/*
 *  Allocation routines and other shortcuts
 */

ubyte *
allocb(bytes)
{
    return(AllocMem(bytes, MEMF_CLEAR|MEMF_PUBLIC));
}

ubyte *
allocl(lwords)
{
    return(AllocMem(lwords<<2, MEMF_CLEAR|MEMF_PUBLIC));
}

bmovl(s,d,n)
char *s,*d;
{
    bmov(s,d,n<<2);
}

/*
 *  Remove tabs in a buffer
 */

detab(ibuf, obuf, maxlen)
register char *ibuf, *obuf;
{
    register short i, j;

    maxlen -= 2;
    for (i = j = 0; ibuf[i] && j < maxlen; ++i) {
	if (ibuf[i] == 9) {
	    do {
		obuf[j++] = ' ';
	    } while ((j & 7) && j < maxlen);
	} else {
	    obuf[j++] = ibuf[i];
	}
    }
    while (j && obuf[j-1] == ' ')
	--j;
    obuf[j] = 0;
    return(j);
}

xefgets(xfi, buf, max)
char *buf;
long xfi;
{
    char ebuf[256];
    if (xfgets(xfi, ebuf, max) >= 0)
	return(detab(ebuf, buf, max));
    return(-1);
}

ncstrcmp(s1, s2)
register ubyte *s1, *s2;
{
    register ubyte c1, c2;

    for (;;) {
	c1 = *s1;
	c2 = *s2;
	if (c1 >= 'A' && c1 <= 'Z') c1 |= 0x20;
	if (c2 >= 'A' && c2 <= 'Z') c2 |= 0x20;
	if (c1 != c2)
	    break;
	if ((c1|c2) == 0)
	    return(0);
	++s1;
	++s2;
    }
    if (c1 < c2)
	return(-1);
    if (c1 > c2)
	return(1);
}

ED *
finded(str, doff)
char *str;
{
    register ED *ed;

    for (ed = (ED *)DBase.mlh_Head; ed->Node.mln_Succ; ed = (ED *)ed->Node.mln_Succ) {
	if (strlen(ed->Name) >= doff && ncstrcmp(str, ed->Name+doff) == 0)
	    return(ed);
    }
    return(NULL);
}

\Rogue\Monster\
else
  echo "will not over write ./src/subs.c"
fi
if [ `wc -c ./src/subs.c | awk '{printf $1}'` -ne 4407 ]
then
echo `wc -c ./src/subs.c | awk '{print "Got " $1 ", Expected " 4407}'`
fi
if `test ! -s ./src/refs.c`
then
echo "writing ./src/refs.c"
cat > ./src/refs.c << '\Rogue\Monster\'

/*
 *  REFS.C
 *
 *  Bringup a cross reference editor window.  The file S:dme.refs and
 *  dme.refs in the current directory are searched for the reference.
 *  If found, the file specified is searched and the segment specified
 *  loaded as a new file in a new window.
 */

#include "defs.h"
#include <stdio.h>

#define PEN    struct _PEN

PEN {
    MNODE   Node;
    char    *path;
};

extern char *breakout();

MLIST	PBase;		/*  special DME paths	*/

/*
 *  Special DME paths for REF and CTAGS
 */

#ifndef NO_DO2

void
do_addpath()
{
    register PEN *pen;
    register short len = strlen(av[1]);

    for (pen = (PEN *)PBase.mlh_Head; pen->Node.mln_Succ; pen = (PEN *)pen->Node.mln_Succ) {
	if (strcmp(av[1], pen->path) == 0)
	    return;
    }
    if (pen = malloc(sizeof(PEN)+len+2)) {
	pen->path = (char *)(pen + 1);
	strcpy(pen->path, av[1]);
	switch(pen->path[len-1]) {
	case ':':
	case '/':
	    break;
	default:
	    strcat(pen->path, "/");
	}
    }
    AddTail(&PBase, pen);
}

do_rempath()
{
    register PEN *pen, *npen;

    for (pen = (PEN *)PBase.mlh_Head; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
	if (wildcmp(av[1], pen->path)) {
	    Remove(pen);
	    free(pen);
	}
    }
}

#endif

#ifndef NO_DO_CTAGS

/*
 *  Implement ctags
 */

void
do_ctags()
{
    char str[64];
    char path[128];
    char buf[128];
    char sbuf[128];
    long xfi;
    short xlen;
    short slen;
    short dbaselen;
    long oldlock = CurrentDir(Ep->dirlock);
    ED *ed;

    {
	register short i, j;

	for (i = Ep->Column; Current[i] == ' '; ++i);
	for (j = i; ; ++j) {
	    register short c = Current[j];
	    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9'))
		continue;
	    break;
	}
	j -= i;
	if (j > 63)
	    j = 63;
	bmov(Current+i, str, j);
	str[j] = 0;
	xlen = j;
    }
    if (!Ep->iconmode)
	title("search tags");
    {
	long xfi;
	PEN *pen, *npen;
	register long i;
	register short j, len;

	dbaselen = dirpart(Ep->Name);
	bmov(Ep->Name, path, dbaselen);
	strcpy(path+dbaselen, "tags");

	/*
	 *  Note: pen not used first pass and set to list head, so next
	 *  pass it will be the first element.
	 *
	 *  Note2:  The file path depends on several factors.  (1) tags in
	 *	    'current' directory, use path to name of current window.
	 *	    (2) tags in directory in DME special path, use special
	 *	    path.  (3) tag entry is a full path name, override
	 *	    previous directories.
	 */

	for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
	    mountrequest(0);
	    if (xfi = xfopen(path, "r", 4096)) {
		mountrequest(1);
		while ((len = xefgets(xfi, buf, 128)) >= 0) {
		    for (j = 0; buf[j] && buf[j] != ' '; ++j);
		    if (j == 0 || buf[0] == '#')
			continue;
		    if (j == xlen && strncmp(str, buf, j) == 0) {
			while (buf[j] == ' ')
			    ++j;
			/*
			 *  Extract the file name into str.  If the
			 *  filename does not contain an absolute path,
			 *  prepend it with such.
			 */
			{
			    char prep = 1;
			    for (i = 0; buf[j] && buf[j] != ' '; ++i, ++j) {
				str[i] = buf[j];
				if (str[i] == ':')
				    prep = 0;
			    }
			    if (prep) {
				bmov(str, str + dbaselen, i);
				bmov(path, str, dbaselen);
				i += dbaselen;
			    }
			}
			str[i] = 0;

			while (buf[j] && buf[j] != '^')     /*  SEARCH ARG */
			    ++j;
			xfclose(xfi);
			if (buf[j] != '^') {
			    title("tags error");
			    goto done;
			}
			++j;
			strcpy(sbuf, buf+j);
			slen = strlen(sbuf);
			if ((ed = finded(str, 0)) == NULL) {
			    strcpy(buf, "newwindow newfile ");
			    strcat(buf, str);
			    do_command(buf);
			    ed = finded(str, 0);
			} else {
			    WindowToFront(ed->Win);
			    ActivateWindow(ed->Win);
			}
			if (ed == NULL) {
			    title("unable to load file");
			    goto done;
			}
			text_switch(ed->Win);
			if (Ep->iconmode)
			    uniconify();
			else
			    text_cursor(0);
			for (i = 0; i < ed->Lines; ++i) {
			    if (strncmp(ed->List[i], sbuf, slen) == 0)
				break;
			}
			sprintf(buf, "first goto %ld", i+1);
			do_command(buf);
			goto done;
		    }
		}
		xfclose(xfi);
	    } else {
		mountrequest(1);
	    }
	    if (npen->Node.mln_Succ) {
		strcpy(path, npen->path);
		strcat(path, "tags");
		dbaselen = strlen(npen->path);
	    }
	}
	title("tag not found");
    }
done:
    CurrentDir(oldlock);
}

#endif

#ifndef NO_DO_REFS

/*
 *  Implement references
 */

void
do_refs()
{
    char str[256];
    char path[128];
    char *srch;
    char *file;
    char *estr;
    long len;
    int bcnt = 10;
    register short i, j;
    short slen, elen;
    long xfi, xfj;
    short tmph, tmpw;
    long oldlock = CurrentDir(Ep->dirlock);

    for (i = Ep->Column; Current[i] == ' '; ++i);     /*  skip spaces     */
    for (j = i       ; ; ++j) {
	if (Current[j] && Current[j] != ' ')
	    continue;
	break;
    }
    j -= i;
    if (j > 63)
	j = 63;
    bmov(Current+i, str, j);
    str[j] = 0;
    title("search .refs");
    {
	register PEN *pen;
	register PEN *npen;

	strcpy(path, "dme.refs");
	mountrequest(0);
	for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
	    if (searchref(path, str, &srch, &file, &len, &estr)) {
		mountrequest(1);
		goto found;
	    }
	    if (npen->Node.mln_Succ) {
		strcpy(path, npen->path);
		strcat(path, "dme.refs");
	    }
	}
	title("Reference not found");
	mountrequest(1);
	goto done;
    }
found:
    title("search file");
    slen = strlen(srch);
    if (estr)
	elen = strlen(estr);
    if (xfi = xfopen(file, "r", 4096)) {
	short lenstr;
	while ((lenstr = xefgets(xfi, str, 256)) >= 0) {
	    if (strncmp(str, srch, slen) == 0) {
		title("load..");
		if (xfj = xfopen("t:dme_ref", "w", 1024)) {
		    tmph = 0;
		    tmpw = 0;
		    do {
			if (lenstr > tmpw)
			    tmpw = strlen(str);
			++tmph;
			xfwrite(xfj, str, strlen(str));
			xfwrite(xfj, "\n", 1);
			if (estr && strncmp(str,estr,elen) == 0)
			    break;
			--len;
		    } while ((lenstr=xefgets(xfi, str, 256)) >= 0 && len);
		    xfclose(xfj);
		    if (tmph > 10)
			tmph = 10;
		    if (tmpw > 80)
			tmpw = 80;
		    sprintf(str, "tmpheight %ld tmpwidth %ld newwindow newfile t:dme_ref", (tmph<<3)+24, (tmpw<<3)+24);
		    do_command(str);
		    unlink("t:dme_ref");
		} else {
		    title("Unable to open t:dme_ref for write");
		}
		xfclose(xfi);
		free(srch);
		free(file);
		if (estr)
		    free(estr);
		goto done;
	    }
	    if (--bcnt == 0) {      /* check break every so so  */
		bcnt = 50;
		if (breakcheck())
		    break;
	    }
	}
	xfclose(xfi);
	title("Search failed");
    } else {
	title("Unable to open sub document");
    }
    free(srch);
    free(file);
    if (estr)
	free(estr);
done:
    CurrentDir(oldlock);
}

/*
 *  Reference file format:
 *
 *  `key' `lines' `file' `searchstring'
 *
 *  where `lines' can be a string instead ... like a read-until, otherwise
 *  the number of lines to read from the reference.
 */

searchref(file, find, psstr, pfile, plines, pestr)
char *file, *find;
char **psstr, **pfile, **pestr;
long *plines;
{
    long xfi;
    char buf[256];
    char *ptr, *base;
    char *b1, *b2, *b3, *b4;
    char quoted;

    if (xfi = xfopen(file, "r", 4096)) {
	while (xefgets(xfi,(base=buf), 256) >= 0) {
	    if (buf[0]=='#')
		continue;
	    ptr = breakout(&base, &quoted, &b1);
	    if (ptr && *ptr && strncmp(ptr, find, strlen(ptr)) == 0) {
		if (ptr = breakout(&base, &quoted, &b2)) {
		    *pestr = NULL;
		    *plines = atoi(ptr);
		    if (*plines == 0) {
			*pestr = (char *)malloc(strlen(ptr)+1);
			strcpy(*pestr, ptr);
		    }
		    if (ptr = breakout(&base, &quoted, &b3)) {
			*pfile = (char *)malloc(strlen(ptr)+1);
			strcpy(*pfile, ptr);
			if (ptr = breakout(&base, &quoted, &b4)) {
			    *psstr = (char *)malloc(strlen(ptr)+1);
			    strcpy(*psstr, ptr);
			    xfclose(xfi);
			    if (b1) free(b1);
			    if (b2) free(b2);
			    if (b3) free(b3);
			    if (b4) free(b4);
			    return(1);
			}
			free(*pfile);
			if (b4)
			    free(b4);
		    }
		    if (pestr)
			free (*pestr);
		    if (b3)
			free (b3);
		}
		if (b2)
		    free(b2);
	    }
	    if (b1)
		free(b1);
	}
	xfclose(xfi);
    }
    return(0);
}

#endif

#ifndef NO_DO_CTAGS

dirpart(str)
register char *str;
{
    register short i;

    for (i = strlen(str) - 1; i >= 0; --i) {
	if (str[i] == '/' || str[i] == ':')
	    break;
    }
    return(i+1);
}

#endif

\Rogue\Monster\
else
  echo "will not over write ./src/refs.c"
fi
if [ `wc -c ./src/refs.c | awk '{printf $1}'` -ne 8371 ]
then
echo `wc -c ./src/refs.c | awk '{print "Got " $1 ", Expected " 8371}'`
fi
if `test ! -s ./src/main.c`
then
echo "writing ./src/main.c"
cat > ./src/main.c << '\Rogue\Monster\'

/*
 * MAIN.C
 *
 *	(C)Copyright 1987 by Matthew Dillon, All Rights Reserved.
 *
 */

#include "defs.h"
#include <local/deemu.h>
#include <local/ipc.h>

short Deemu[] = {
    DMSTRT, 0, 0,
    DMNW,   0,10,32,16,-64,-80,0xFFFF,
    DMEND,  0, 0
};

#define DMNWOFF 4

#define IDCMPFLAGS   CLOSEWINDOW|NEWSIZE|RAWKEY|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE|MENUPICK

extern WIN *OpenWindow();
extern char *menu_cmd();

NW Nw = {
   0, 1, 0  , 0  , -1, -1,  /*	width, height filled in by program */
   IDCMPFLAGS,
   ACTIVATE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|RMBTRAP,
   NULL, NULL, (ubyte *)"   WAIT   ",
   NULL, NULL,
   32, 32, -1, -1,
   WBENCHSCREEN
};

short Sharedrefs;
short Oldtlen = 999;	  /*  Old Title Length	  */
struct MsgPort *Sharedport;
DISKOBJ *Do;
WBS	*Wbs;

WIN *Win;
RP  *Rp;

short Xsize,  Ysize;		/* font character sizes        */
short Rows,  Columns;		/* character rows/cols available       */
short Xbase,  Ybase;		/* offset pixel base for display       */
short XTbase,YTbase;		/* used for text display	       */
short Xpixs,  Ypixs;		/* actual # X/Y pixels available       */
short Mx, My;

ubyte *av[8];
char Quitflag;
char Overide;
char SizeOveride;
char Wdisable = 1;		/* Disable icon save		       */
char MShowTitle, MForceTitle;
short Nwwidth, Nwheight, Nwtopedge, Nwleftedge, Nwtmpwidth, Nwtmpheight;

PORT *IPCPort;
PORT *IPCRPort;
long Mask;

int Enable_Abort;

extern WIN   *opensharedwindow();

static char *Ffile;

main(mac, mav)
char *mav[];
{
    char nf, ni;	    /*	# files on command line     */
    char notdone;	    /*	for endless loop	    */
    char iawm = 0;	    /*	overide mouse buttons	    */
    char dontwait = 0;	    /*	don't wait for a message    */
    short i;
    short Code;
    PROC *proc = (PROC *)FindTask(NULL);
    long origlock;

    origlock = CurrentDir(DupLock(proc->pr_CurrentDir));

    NewList(&DBase);
    NewList(&PBase);
    if (!openlibs(INTUITION_LIB|GRAPHICS_LIB))
	exiterr("cannot open intuition or graphics library");
    initipc();

    InitDeemuNW(Deemu+DMNWOFF, &Nw);

    init_command();

    Nwwidth	= Nw.Width;	/*  Parameters for new windows	*/
    Nwheight	= Nw.Height;
    Nwtopedge	= Nw.TopEdge;
    Nwleftedge	= Nw.LeftEdge;

    Enable_Abort= 0;		/*  disable break		*/

    String  = (char *)malloc(1);        /*  initialize scanf variable   */
    *String = 0;


    if (mac == 0) {             /*  WORKBENCH STARTUP           */

	Wdisable = 0;		/*  allow icon save		*/
	Wbs = (WBS *)mav;
	if (!openlibs(ICON_LIB))
	    exiterr("unable to open icon library");
	UnLock(CurrentDir(DupLock(Wbs->sm_ArgList[0].wa_Lock)));   /* Tool */
	Do = GetDiskObject(Wbs->sm_ArgList[0].wa_Name);
	if (Do == NULL)
	    exiterr("unable to get disk object");
	mac = 99;
    }

#if AREXX
    mountrequest(0);
    openrexx();     /* do this after the last possible call to exiterr() */
    mountrequest(1);
#endif

    resethash();

    if (Do) {
	ops(Do->do_ToolTypes, 1);
	nf = Wbs->sm_NumArgs - 1;
	UnLock(CurrentDir(DupLock(Wbs->sm_ArgList[0].wa_Lock)));
    } else {
	nf = ops(mav+1, 0);
    }

    for (ni = 0, i = 1; i < mac; ++i) {
	register char *str;
	register DISKOBJ *dso;
	if (Wbs) {
	    if (i > nf)
		break;
	    str = Wbs->sm_ArgList[i].wa_Name;
	    UnLock(CurrentDir(DupLock(Wbs->sm_ArgList[i].wa_Lock)));
	    if (dso = GetDiskObject(Wbs->sm_ArgList[i].wa_Name)) {
		ops(dso->do_ToolTypes, 1);
		FreeDiskObject(dso);
	    }
	} else {
	    str = mav[i];
	    if (*str == '-')
		continue;
	}
	do_newwindow(nf > 1, ni * 10);
	++ni;
	av[0] = (ubyte *)"newfile";
	av[1] = (ubyte *)str;
	do_edit();
	MForceTitle = 1;
	window_title();
    }
    if (nf == 0)                    /* no files to edit */
	do_newwindow(nf > 1, ni * 10);

    mountrequest(0);
    av[0] = NULL;
    av[1] = (ubyte *)"s:.edrc";
    do_source();
    av[0] = NULL;
    av[1] = (ubyte *)((Ffile) ? Ffile : ".edrc");
    do_source();
    mountrequest(1);
    {			    /*	1.29c	*/
	register ED *ep;
	register ED *eb = Ep;
	if (eb) {
	    for (ep = (ED *)eb->Node.mln_Succ; ep->Node.mln_Succ; ep = (ED *)ep->Node.mln_Succ) {
		ep->Tabstop = eb->Tabstop;
		ep->Margin  = eb->Margin;
		ep->Insertmode = eb->Insertmode;
		ep->IgnoreCase = eb->IgnoreCase;
		ep->Wordwrap   = eb->Wordwrap;
		if (eb->Font) {
		    ep->Font = eb->Font;
		    ++eb->Font->tf_Accessors;
		}
	    }
	}
    }
    title("DME V1.31 \251Copyright 1988 by Matthew Dillon,  All Rights Reserved                  ");
    Mask |= 1 << Win->UserPort->mp_SigBit;
loop:
    if (!Ep->iconmode)
	text_cursor(1);
    for (notdone = 1; !Quitflag && notdone;) {
	char mmove = 0;
	short mqual;

	if (!Ep->iconmode)
	    window_title();
	if (dontwait) {
	    --dontwait;
	} else {
	    Wait(Mask);
	}

	/*
	 *  NOTE: due to operation of breakcheck(), the userport signal
	 *  may not be set even if there are messages pending.
	 *
	 *  NOTE2: CheckPort() requires dres.library, which will be loaded
	 *  if IPCPort exists because the IPC needs it also.
	 */

	if (IPCPort && CheckPort(IPCPort))
	    ipchandler();
	{
	    register IMESS *im;
	    while (im = (IMESS *)GetMsg(Win->UserPort)) {
		Msgchk = 1;
		Abortcommand = 0;
		Code = im->Code;
		if (im->IDCMPWindow != Win) {
		    Overide = 0;
		    if (Comlinemode)
			escapecomlinemode();
		    text_sync();
		    MShowTitle = 0;
		    if (!Ep->iconmode)
			window_title();
		    if (text_switch(im->IDCMPWindow) == 0) {
			ReplyMsg(im);
			continue;
		    }
		}
		Mx = im->MouseX;
		My = im->MouseY;
		switch(im->Class) {
		case NEWSIZE:
		    if (!Ep->iconmode) {
			if (Comlinemode)
			    escapecomlinemode();
			set_window_params();
			if (!text_sync())
			text_redisplay();
			text_cursor(1);
		    }
		    break;
		case MOUSEBUTTONS:
		    switch(Code) {
		    case SELECTDOWN:
		    case MENUDOWN:
			if (Ep->iconmode || iawm) {
			    uniconify();
			    break;
			}
			ReportMouse(-1, Win);
			uniconify();
			text_cursor(0);
			keyctl(NULL, im->Code|0x80, im->Qualifier);
			text_cursor(1);
			break;
		    case SELECTUP:
		    case MENUUP:
			ReportMouse(0, Win);
			break;
		    }
		    break;
		case RAWKEY:
		    if ((im->Code & 0x80) == 0) {
			/*  Handled in command interpreter.
			if (Ep->iconmode) {
			    uniconify();
			    break;
			}
			*/
			text_cursor(0);
			keyctl(im, im->Code, im->Qualifier);
			text_cursor(1);
		    }
		    break;
		case MENUPICK:
		    {
			register char *str = menu_cmd(im);
			if (str) {
			    str = strcpy(malloc(strlen(str)+1), str);
			    text_cursor(0);
			    do_command(str);
			    free(str);
			    text_cursor(1);
			}
		    }
		    break;
		case CLOSEWINDOW:
		    if (Comlinemode)
			escapecomlinemode();
		    text_sync();
		    notdone = 0;
		    break;
		case ACTIVEWINDOW:
		    if (!Ep->iconmode)
			iawm = 1;
		    break;
		case MOUSEMOVE:
		    mmove = 1;
		    mqual = im->Qualifier;
		    break;
		}
		if (im)
		    ReplyMsg(im);
		if (notdone == 0 || Quitflag) {
		    dontwait = 2;
		    goto boom;
		}
	    }
	}

	iawm = 0;
	if (mmove) {
	    uniconify();
	    mmove = 0;
	    text_cursor(0);
	    keyctl(NULL, QMOVE, mqual);
	    text_cursor(1);
	}
	closesharedwindow(NULL);
    }
boom:
    text_sync();
    if (Ep->Modified && !Overide) {
	uniconify();
	Overide = 1;
	title("*** File has been modified ***");
	Quitflag = 0;
	goto loop;
    }
    SetWindowTitles(Win, "", -1);
    text_uninit();                        /* uninitialize text portion    */
    closesharedwindow(Win);
    if (((ED *)DBase.mlh_Head)->Node.mln_Succ) {
	Quitflag = 0;
	Win = Ep->Win;			  /* make arbitrary other window act. */
	Rp = Win->RPort;
	if (!Ep->iconmode)
	    set_window_params();
	text_load();
	MShowTitle = 0;
	goto loop;
    }
    closesharedwindow(NULL);
    if (Do)
	FreeDiskObject(Do);
#if AREXX
    closerexx();
#endif
    UnLock(CurrentDir(origlock));
    if (IPCPort)
	CloseIPC(IPCPort);
    if (IPCRPort)
	DeletePort(IPCRPort);
    closelibs(-1);
    dealloc_hash();
}

ipchandler()
{
    register IPCMSG *msg;
    register char *ptr;
    while (msg = (IPCMSG *)GetMsg(IPCPort)) {
	register long error = 0;
	if (ptr = (char *)msg->TBuf) {      /*  Valid msg,  */
	    register ED *ed;
					    /*	For this project  */
	    if (ptr[0] == 0)
		ed = Ep;
	    else if ((ed = finded(ptr, 0)) == NULL)
		error = IF_NOTFND;
	    if (ed) {
		if (ed != Ep)
		    text_switch(ed->Win);
		if (!Ep->iconmode)
		    text_cursor(0);
		while (*ptr++);                 /*  Skip Project Name */
		do_command(ptr);
	    }
	}
	ReplyIPC(msg, NULL, 0, error);
    }
}

/*
 *  If it is possible, create an IPC port for DME.  IF_ALLOC specifies that
 *  incomming static messages should be re-allocated automatically because
 *  we will be destroying the input buffer for messages we process.
 */

initipc()
{
    if (openlibs(DRES_LIB)) {
	if (IPCPort = OpenIPC("dme.CMD", IF_ALLOC)) {
	    Mask |= 1 << IPCPort->mp_SigBit;
	    IPCRPort = CreatePort(NULL,0);
	}
    }
}

/*
 *  IPC appname projname command
 */

void
do_ipc()
{
    char *buf;
    char buf2[64];
    IPCMSG msg;
    short len;

    if (!IPCPort)
	initipc();
    if (!IPCPort) {
	Abortcommand = 1;
	title("dres.library not installed");
	return;
    }
    buf = malloc(len = strlen(av[2])+strlen(av[3])+2);
    strcpy(buf, av[2]);
    strcpy(buf+strlen(buf)+1, av[3]);
    strcpy(buf2, av[1]);
    strcat(buf2, ".CMD");
    msg.Msg.mn_ReplyPort = IPCRPort;
    msg.TBuf = (APTR)buf;
    msg.TLen = len;
    msg.TFlags = IF_NOCOPY;
    DoIPC2(buf2, &msg, ipchandler, IPCPort);
    if (msg.RFlags & IF_ERROR) {
	if (msg.RFlags & IF_NOAPP)
	    title("Application not found");
	else
	    title("Remote error");
    }
    FreeIPC(&msg);
    free(buf);
}

do_iconify()
{
    text_sync();
    if (!Comlinemode)
	iconify();
}

do_tomouse()
{
    text_position((Mx-Xbase)/Xsize, (My-Ybase)/Ysize);
}

iconify()
{
    if (!Ep->iconmode) {
	Ep->Winx      = Win->LeftEdge;
	Ep->Winy      = Win->TopEdge;
	Ep->Winwidth  = Win->Width;
	Ep->Winheight = Win->Height;
	Nw.Height = 10;
	Nw.Width  = 20 + 5*8 + strlen(Ep->Name)*8;
	Nw.LeftEdge= Ep->IWinx;
	Nw.TopEdge = Ep->IWiny;
	if (Nw.LeftEdge + Nw.Width > Win->WScreen->Width)
	    Nw.LeftEdge = Win->WScreen->Width - Nw.Width;
	if (Nw.TopEdge + Nw.Height > Win->WScreen->Height)
	    Nw.TopEdge = Win->WScreen->Height - Nw.Height;
	Nw.Title = Ep->Wtitle;
	Nw.Flags &= ~(WINDOWSIZING|WINDOWDEPTH|ACTIVATE);
	Nw.Flags |= BORDERLESS;
	Nw.BlockPen = (Ep->Modified) ? 3 : -1;
	sprintf(Ep->Wtitle, "%s     ", Ep->Name);
	if (Win->Flags & WINDOWACTIVE)      /*  KTS */
	    Nw.Flags |= ACTIVATE;
	closesharedwindow(Win);
	Win = Ep->Win = opensharedwindow(&Nw);
	Nw.BlockPen = -1;
	Nw.Flags |= WINDOWSIZING|WINDOWDEPTH;
	Nw.Flags &= ~BORDERLESS;
	Rp = Win->RPort;
    }
    Ep->iconmode = 1;
}

uniconify()
{
    if (Ep->iconmode) {
	Ep->IWinx = Win->LeftEdge;
	Ep->IWiny = Win->TopEdge;
	closesharedwindow(Win);
	Nw.LeftEdge = Ep->Winx;
	Nw.TopEdge  = Ep->Winy;
	Nw.Width    = Ep->Winwidth;
	Nw.Height   = Ep->Winheight;
	Nw.Title    = Ep->Wtitle;
	Win = Ep->Win = opensharedwindow(&Nw);
	menu_strip(Win);
	Rp = Win->RPort;
	if (Ep->Font)
	    SetFont(Rp, Ep->Font);
	set_window_params();
	if (!text_sync())
	    text_redisplay();
	text_cursor(1);
	MShowTitle = 0;
	window_title();
    }
    Ep->iconmode = 0;
}


do_newwindow(makesmall, deltaheight)
{
    WIN *win;
    int msadj = makesmall;

    if (SizeOveride)
	msadj = 0;
    if (Ep)
	text_sync();
    Nw.Title = (ubyte *)"    OK    ";
    Nw.Width = (Nwtmpwidth) ? Nwtmpwidth : Nwwidth;
    Nw.Height= (Nwtmpheight)? Nwtmpheight: Nwheight;
    Nwtmpwidth = Nwtmpheight = 0;
    Nw.LeftEdge = Nwleftedge;
    Nw.TopEdge	= Nwtopedge;
    if (msadj > 0) {                    /* deltaheight must be valid    */
	Nw.TopEdge = deltaheight + 16;
	Nw.LeftEdge= 10*8;
	Nw.Flags &= ~ACTIVATE;
	Nw.Width = 40*8;
	Nw.Height= 10*8;
	if (Nw.TopEdge + Nw.Height > 200)
	    Nw.TopEdge = deltaheight = 200 - Nw.Height;
    }
    win = opensharedwindow(&Nw);
    menu_strip(win);
    Nw.Flags |= ACTIVATE;
    if (win) {
	Win = win;			/* set new window   */
	Rp = Win->RPort;
	set_window_params();
	text_init();                    /* initialize       */
	text_load();
	if (makesmall != -1)            /* if deltaheight valid */
	    Ep->IWiny = deltaheight + 16;
    }
}

WIN *
TOpenWindow(nw)
NW *nw;
{
    WIN *win;

    while ((win = OpenWindow(nw)) == NULL) {
	if (nw->Width < 50 || nw->Height < 50)
	    break;
	nw->Width -= 10;
	nw->Height-= 10;
    }
    return(win);
}


WIN *
opensharedwindow(nw)
NW *nw;
{
    WIN *win;

    if (Sharedport)
	nw->IDCMPFlags = NULL;
    else
	nw->IDCMPFlags = IDCMPFLAGS;
    win = TOpenWindow(nw);
    if (win) {
	if (Sharedport) {
	    win->UserPort = Sharedport;
	    ModifyIDCMP(win, IDCMPFLAGS);
	} else {
	    Sharedport = win->UserPort;
	}
	++Sharedrefs;
    }
    return(win);
}


closesharedwindow(win)
WIN *win;
{
    static WIN *wunlink;
    register IMESS *im;
    char notoktoclosenow = 0;

    if (win) {
	SetWindowTitles(win, "", -1);
	ClearMenuStrip(win);
	Forbid();
	win->UserPort = NULL;
	ModifyIDCMP(win, GADGETUP);     /* NEVER occurs */

	notoktoclosenow = 1;

	Permit();
	if (notoktoclosenow) {
	    win->UserData = (char *)wunlink;
	    wunlink = win;
	} else {
	    CloseWindow(win);
	}
	--Sharedrefs;
    } else {
	if (Sharedrefs == 0 && Sharedport) {
	    DeletePort(Sharedport);
	    Sharedport = NULL;
	}
	for (win = wunlink; win; win = wunlink) {
	    wunlink = (WIN *)win->UserData;
	    CloseWindow(win);
	}
	wunlink = NULL;
    }
}


getyn(text)
char *text;
{
    int result;
    ITEXT *body, *pos, *neg;

    body = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
    pos  = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
    neg  = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
    bzero(body, sizeof(ITEXT));
    bzero(pos , sizeof(ITEXT));
    bzero(neg , sizeof(ITEXT));
    body->BackPen = pos->BackPen = neg->BackPen = 1;
    body->DrawMode= pos->DrawMode= neg->DrawMode= AUTODRAWMODE;
    body->LeftEdge = 10;
    body->TopEdge  = 12;
    body->IText    = (ubyte *)text;
    pos->LeftEdge = AUTOLEFTEDGE;
    pos->TopEdge = AUTOTOPEDGE;
    pos->IText = (ubyte *)"OK";
    neg->LeftEdge = AUTOLEFTEDGE;
    neg->TopEdge = AUTOTOPEDGE;
    neg->IText = (ubyte *)"CANCEL";
    result = AutoRequest(Win,body,pos,neg,0,0,320,58);
    FreeMem(body, sizeof(ITEXT));
    FreeMem(pos , sizeof(ITEXT));
    FreeMem(neg , sizeof(ITEXT));
    return(result);
}


title(buf)
char *buf;
{
    SetWindowTitles(Win, buf, -1);
    Oldtlen = 999;
    MShowTitle = 3;
}

window_title()
{
    register int len, maxlen;

    if (memoryfail) {
	title(" -- NO MEMORY -- ");
	memoryfail = 0;
	text_redisplay();
    }
    if (MForceTitle) {
	MShowTitle = 0;
	MForceTitle = 0;
    }
    if (MShowTitle) {
	--MShowTitle;
	return(0);
    }
    {
	register char *mod;
	FONT *oldfont;

	mod = (Ep->Modified) ? " (modified)" : "          ";
	sprintf(Ep->Wtitle, "%3ld/%-3ld %3ld %s%s  ", text_lineno(), text_lines(), text_colno()+1, text_name(), mod);
	if (!text_imode())
	    strcat(Ep->Wtitle, "Ovr ");
	len = strlen(Ep->Wtitle);
	if (len < Columns && Columns < 128) {
	    bset(Ep->Wtitle+len, Columns - len + 1, ' ');
	    Ep->Wtitle[Columns + 1] = 0;
	}

	/*
	 *  Update title
	 */

	oldfont = Win->RPort->Font;
	SetFont(Win->RPort, Win->WScreen->RastPort.Font);

	Win->Title = Ep->Wtitle;
	SetAPen(Rp, 0);
	SetBPen(Rp, 1);
	Move(Rp, 30, Win->RPort->Font->tf_Baseline+1);
	maxlen = (Win->Width-96)/Win->RPort->Font->tf_XSize;
	if (maxlen < 0)
	    maxlen = 0;
	if (len > maxlen)
	    len = Oldtlen = maxlen;
	if (Oldtlen > maxlen)
	    Oldtlen = maxlen;
	Text(Rp, Ep->Wtitle, len);      /*  No flash                    */
	while (Oldtlen - len >= (int)sizeof(Space)) {
	    Text(Rp, Space, sizeof(Space));
	    Oldtlen -= sizeof(Space);
	}
	if (Oldtlen - len > 0)
	    Text(Rp, Space, Oldtlen - len);
	Oldtlen = len;			/*  Oldtlen might have been <	*/
	SetAPen(Rp, 1);
	SetBPen(Rp, 0);

	SetFont(Win->RPort, oldfont);
    }
}

set_window_params()
{
    Xsize = Rp->Font->tf_XSize;
    Ysize = Rp->Font->tf_YSize;
    Xbase = Win->BorderLeft;
    Ybase = Win->BorderTop;
    Xpixs   = Win->Width - Win->BorderRight - Xbase;
    Ypixs   = Win->Height- Win->BorderBottom- Ybase;
    Columns = Xpixs / Xsize;
    Rows    = Ypixs / Ysize;
    XTbase  =  Xbase;
    YTbase  =  Ybase + Rp->Font->tf_Baseline;
}


exiterr(str)
char *str;
{
    if (Output()) {
	Write(Output(),str,strlen(str));
	Write(Output(),"\n",1);
    }
    exit(1);
}


/*
 *  Check break by scanning pending messages in the I stream for a ^C.
 *  Msgchk forces a check, else the check is only made if the signal is
 *  set in the I stream (the signal is reset).
 */

breakcheck()
{
    IMESS *im;
    register struct List *list = &Win->UserPort->mp_MsgList;

    if (Msgchk || (SetSignal(0,0) & (1<<Win->UserPort->mp_SigBit))) {
	Msgchk = 0;
	SetSignal(0,1<<Win->UserPort->mp_SigBit);

	im = (IMESS *)list->lh_Head;
	Forbid();
	for (; im != &list->lh_Tail; im = (IMESS *)im->ExecMessage.mn_Node.ln_Succ) {
	    if (im->Class == RAWKEY && (im->Qualifier & 0xFB) == 0x08 &&
		im->Code == CtlC) {

		Permit();
		SetSignal(SIGBREAKF_CTRL_C,SIGBREAKF_CTRL_C);
		return(1);
	    }
	}
	Permit();
    }
    return(0);
}

breakreset()
{
    SetSignal(0, SIGBREAKF_CTRL_C);
}

/*
 *  leftedge n
 *  topedge  n
 *  width    n
 *  height   n
 *  tmpwidth  n
 *  tmpheight n
 */

void
do_windowparm()
{
    int val = atoi(av[1]);

    if (av[0][0] == 't' && av[0][1] == 'm') {   /*  tmpwidth/tmpheight  */
	if (av[0][3] == 'w')
	    Nwtmpwidth = val;
	if (av[0][3] == 'h')
	    Nwtmpheight= val;
	return;
    }
    switch(av[0][0]) {
    case 'l':
	Nwleftedge = val;
	break;
    case 't':
	Nwtopedge = val;
	break;
    case 'w':
	Nwwidth = val;
	break;
    case 'h':
	Nwheight = val;
	break;
    }
}

/*
 *  resize cols rows
 */

do_resize()
{
    int cols = atoi(av[1]);
    int rows = atoi(av[2]);
    short width = (cols*Win->RPort->Font->tf_XSize) + Win->BorderLeft + Win->BorderRight;
    short height= (rows*Win->RPort->Font->tf_YSize) + Win->BorderTop + Win->BorderBottom;

    if (width < 16 || height < 16 ||
    width > Win->WScreen->Width - Win->LeftEdge ||
    height > Win->WScreen->Height - Win->TopEdge) {
	title ("window too big (try moving to upper left corner and retrying)");
	return(0);
    }
    SizeWindow(Win, width - Win->Width, height - Win->Height);
    Delay(50*2);    /* wait 2 seconds */
}

ops(av, iswb)
register char *av[];
{
    register short nonops;
    register short i;
    register long val;
    register char *str;

    for (i = nonops = 0; str = av[i]; ++i) {
	if (iswb) {
	    if (strncmp(str, "ARG", 3) == 0) {
		while (*str && *str != '-')
		    ++str;
	    }
	}
	if (*str == '-') {
	    val = atoi(str+2);
	    switch(str[1]) {
	    case 'f':
		Ffile = str+2;
		break;
	    case 'b':
		SizeOveride = 1;
		break;
	    case 't':
		Nwtopedge = val;
		break;
	    case 'l':
		Nwleftedge= val;
		break;
	    case 'w':
		SizeOveride = 1;
		Nwwidth   = val;
		break;
	    case 'h':
		SizeOveride = 1;
		Nwheight  = val;
		break;
	    }
	} else {
	    ++nonops;
	}
    }
    return(nonops);
}



\Rogue\Monster\
else
  echo "will not over write ./src/main.c"
fi
if [ `wc -c ./src/main.c | awk '{printf $1}'` -ne 19086 ]
then
echo `wc -c ./src/main.c | awk '{print "Got " $1 ", Expected " 19086}'`
fi
if `test ! -s ./src/rexx.c`
then
echo "writing ./src/rexx.c"
cat > ./src/rexx.c << '\Rogue\Monster\'

/*
 *  REXX.C
 *
 *	(c) Copyright 1987 by Kim DeVaughn, All Rights Reserved
 *
 *  ARexx interface code, etc.
 *
 */


#include "defs.h"
#include "rexx.h"

#if AREXX

int foundcmd;	    /* control for implicit ARexx macro invocation   */
int cmderr;	    /* global command error flag for do_rexx()'s use */

/*
APTR OpenLibrary();
APTR FindPort();
APTR GetMsg();
*/
APTR CreateRexxMsg();
APTR CreateArgstring();

struct RxsLib *RexxSysBase;



/*
 * initialization for ARexx ... just open rexsyslib.library
 */

void
openrexx()
{
    RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", (ULONG)RXSVERS);
    return;
}



/*
 * cleanup any open ARexx stuff ...  just close rexsyslib.library for now
 */

void
closerexx()
{
    if (RexxSysBase) {
	CloseLibrary(RexxSysBase);
    }
    return();
}



/*
 *  explicit invocation interface between do_command() and do_rexx
 *  for ARexx macros having NO arguments (i.e., for the "rx" command)
 */

do_rx()
{
    do_rexx(av[1]);
    return();
}



/*
 *  explicit invocation interface between do_command() and do_rexx
 *  for ARexx macros having ONE argument (i.e., for the "rx1" command)
 */

do_rx1()
{
    char macbuf[256];

    strcpy(macbuf, av[1]);
    strcat(macbuf, " ");
    strcat(macbuf, av[2]);
    do_rexx(macbuf);
    return();
}



/*
 *  explicit invocation interface between do_command() and do_rexx
 *  for ARexx macros having TWO arguments (i.e., for the "rx2" command)
 */

do_rx2()
{
    char macbuf[256];

    strcpy(macbuf, av[1]);
    strcat(macbuf, " ");
    strcat(macbuf, av[2]);
    strcat(macbuf, " ");
    strcat(macbuf, av[3]);
    do_rexx(macbuf);
    return();
}



/*
 *  implicit invocation interface between do_command() and do_rexx
 *  for ARexx macros implicitly called; arbitrary number of arguments
 */

do_rxImplied(cmd, args)
char *cmd;
char *args;
{
    char macbuf[256];

    strcpy(macbuf, cmd);
    strcat(macbuf, " ");
    strcat(macbuf, args);
    do_rexx(macbuf);
    return();
}



/*
 *  issue a command to ARexx ...
 */

do_rexx(macstr)
char *macstr;
{
    struct RexxArg *macarg;

    struct MsgPort  RexxPort;
    struct MsgPort *ARexxPort;

    struct RexxMsg *macptr;
    struct RexxMsg *cmdptr;

    char host[16];
    char hexbuf[12];	    /* should only need 9 bytes */
    char errmsg[80];	    /* don't build a larger error message */

    int  ret;
    int  err;


    if (RexxSysBase == 0) {
	title("Unknown Command   -   No Macros:  ARexx Not Installed ");   /* no rexxsyslib */
	return(0);
    }


    ClearMem(&RexxPort, sizeof(struct MsgPort));
    strcpy(host, "DME");
    sprintf(hexbuf, "%08x", &RexxPort);
    strcat(host, hexbuf);
    InitPort(&RexxPort, host);      /* need to error check this */
    AddPort(&RexxPort);
    /* return here if InitPort failed */


    if (macarg = (struct RexxArg *)CreateArgstring(macstr, strlen(macstr))) {
	if (macptr = (struct RexxMsg *)CreateRexxMsg(&RexxPort, "dme", host)) {
	    ACTION(macptr) = RXCOMM;
	    ARG0(macptr)   = (STRPTR)macarg;

	    Forbid();
	    if (ARexxPort = (struct MsgPort *)FindPort("REXX")) {
		PutMsg(ARexxPort, macptr);
		Permit();
		title("Calling ARexx Macro ... ");

		for (;;) {
		    WaitPort(&RexxPort);
		    cmdptr = (struct RexxMsg *)GetMsg(&RexxPort);

		    if (IsRexxMsg(cmdptr)) {

			foundcmd = 0;
			cmderr = CMD_INITIAL;
			ret = do_command(ARG0(cmdptr));
			err = cmderr;
			if (foundcmd) {
			    ret = (ret == 1) ? 0 : 5;   /* cmd error:  RC = 5  */
			} else {
			    ret = do_rexx(ARG0(cmdptr));    /* another macro? */
			}

			RESULT1(cmdptr) = ret;
			RESULT2(cmdptr) = 0;
			ReplyMsg(cmdptr);
		    }
		    do_command("null");     /* a kludge to set "foundcmd" */
		    if (macptr == cmdptr) break;
		}


		if (ret = RESULT1(cmdptr)) {
		    if (RESULT2(cmdptr)) {
			if (RESULT2(cmdptr) == 1) {
			    title("Unknown Command ");
			} else {
			    sprintf(errmsg, "ARexx Macro Error:  Code = %d  Severity = %d ", RESULT2(cmdptr), ret);
			    title(errmsg);
			}
		    } else {
			sprintf(errmsg, "User Specified Macro Error:  RC = %d ", ret);
			title(errmsg);
		    }
		} else {
		    if (err <= TITLE_THRESHHOLD) {
			title("OK ");
		    }
		}
		ret = ret + err;
	    } else {
		Permit();
		title("Unknown Command   -   No Macros:  ARexx Not Active ");   /* no REXX port */

		ret = -1;
	    }
	    DeleteRexxMsg(macptr);
	} else {
	    title("CreateRexxMsg() Failed ");   /* may be overkill, and not need to ckeck this */
	    ret = -1;
	}
	DeleteArgstring(macarg);
    } else {
	title("CreateArgstring() Failed ");     /* may be overkill, and not need to check this */
	ret = -1;
    }


    RemPort(&RexxPort);
    FreePort(&RexxPort);
    return(ret);
}

#endif

\Rogue\Monster\
else
  echo "will not over write ./src/rexx.c"
fi
if [ `wc -c ./src/rexx.c | awk '{printf $1}'` -ne 4689 ]
then
echo `wc -c ./src/rexx.c | awk '{print "Got " $1 ", Expected " 4689}'`
fi
if `test ! -s ./src/Makefile`
then
echo "writing ./src/Makefile"
cat > ./src/Makefile << '\Rogue\Monster\'

#   Makefile for DME
#
#   You *need* my support libraries to compile this

SYMS=	include:symbols.m
SYMC=	include:local/makesymbols.c
OD=	T:

EXE= /c/dme

AFLAGS= -iSYS2:asm
CFLAGS= +L +I$(SYMS) -E1000

OB0=   $(OD)main.o
OB1=   $(OD)command.o
OB2=   $(OD)keyboard.o
OB3=   $(OD)globals.o
OB4=   $(OD)cmd1.o
OB5=   $(OD)cmd2.o
OB6=   $(OD)cmd3.o
OB7=   $(OD)subs.o
OB8=   $(OD)refs.o
OB9=   $(OD)filereq.o
OBA=   $(OD)menu.o
OBB=   $(OD)mods.o
OBC=   $(OD)rexx.o
OBD=   $(OD)rexxbind.o

SR0=   main.c
SR1=   command.c
SR2=   keyboard.c
SR3=   globals.c
SR4=   cmd1.c
SR5=   cmd2.c
SR6=   cmd3.c
SR7=   subs.c
SR8=   refs.c
SR9=   filereq.c
SRA=   menu.c
SRB=   mods.c
SRC=   rexx.c
SRD=   rexxbind.asm

OBJS= $(OB0) $(OB1) $(OB2) $(OB3) $(OB4) $(OB5) $(OB6) $(OB7) $(OB8) $(OB9) $(OBA) $(OBB) $(OBC) $(OBD)

$(EXE): $(SYMS) $(OBJS)
    ln +Q $(OBJS) -ldres -lsup32 -lc32 -O $(EXE)

clean:
    -delete $(OBJS)

$(OB0): $(SR0)
    cc $(CFLAGS) $(SR0) -o $(OB0)
$(OB1): $(SR1)
    cc $(CFLAGS) $(SR1) -o $(OB1)
$(OB2): $(SR2)
    cc $(CFLAGS) $(SR2) -o $(OB2)
$(OB3): $(SR3)
    cc $(CFLAGS) $(SR3) -o $(OB3)
$(OB4): $(SR4)
    cc $(CFLAGS) $(SR4) -o $(OB4)
$(OB5): $(SR5)
    cc $(CFLAGS) $(SR5) -o $(OB5)
$(OB6): $(SR6)
    cc $(CFLAGS) $(SR6) -o $(OB6)
$(OB7): $(SR7)
    cc $(CFLAGS) $(SR7) -o $(OB7)
$(OB8): $(SR8)
    cc $(CFLAGS) $(SR8) -o $(OB8)
$(OB9): $(SR9)
    cc $(CFLAGS) $(SR9) -o $(OB9)
$(OBA): $(SRA)
    cc $(CFLAGS) $(SRA) -o $(OBA)
$(OBB): $(SRB)
    cc $(CFLAGS) $(SRB) -o $(OBB)
$(OBC): $(SRC)
    cc $(CFLAGS) $(SRC) -o $(OBC)
$(OBD): $(SRD)
    as $(AFLAGS) $(SRD) -o $(OBD)

$(SYMS):    $(SYMC)
    make -f include:local/Makefile


\Rogue\Monster\
else
  echo "will not over write ./src/Makefile"
fi
if [ `wc -c ./src/Makefile | awk '{printf $1}'` -ne 1655 ]
then
echo `wc -c ./src/Makefile | awk '{print "Got " $1 ", Expected " 1655}'`
fi
if `test ! -s ./src/cmd2.c`
then
echo "writing ./src/cmd2.c"
cat > ./src/cmd2.c << '\Rogue\Monster\'

/*
 * CMD2.C   (was TEXT2.C)
 *
 *	(C)Copyright 1987 by Matthew Dillon, All Rights Reserved
 */

#include "defs.h"
#include <stdio.h>

#define nomemory()  {memoryfail = 1;}

#if AREXX
#include "rexx.h"
extern int foundcmd;	   /* control for implicit ARexx macro invocation   */
extern int cmderr;	   /* global command error flag for do_rexx()'s use */
#endif

extern char MForceTitle;
extern void do_bmove();



ED *
uninit_init(ep)
register ED *ep;
{
    short iwinx, iwiny;
    char  tabstop, margin, insertmode, wordwrap;
    FONT  *font;
    long lock = DupLock(ep->dirlock);

    iwinx = ep->IWinx;
    iwiny = ep->IWiny;
    tabstop= ep->Tabstop;
    margin = ep->Margin;
    insertmode = ep->Insertmode;
    wordwrap = ep->Wordwrap;
    font = ep->Font;
    ep->Font = NULL;
    text_uninit();
    text_init();
    ep = Ep;
    if (ep->Font)
	CloseFont(ep->Font);
    ep->Font = font;
    ep->IWiny = iwiny;
    ep->IWinx = iwinx;
    ep->Tabstop = tabstop;
    ep->Margin	= margin;
    ep->Insertmode = insertmode;
    ep->Wordwrap = wordwrap;
    ep->Modified = 0;
    ep->Line = ep->Topline = 0;
    UnLock(ep->dirlock);
    ep->dirlock = lock;
    return(ep);
}


do_remeol()
{
    Current[Clen = Ep->Column] = 0;
    text_sync();
    text_redisplaycurrline();
}

do_wleft()
{
    register ED *ep = Ep;
    register ubyte *ptr;
    register int i;

    for (;;) {
	i = ep->Column;
	if (i == 0)
	    goto prevline;
	--i;
	while (i && Current[i] == ' ')
	    --i;
	if (i == 0 && Current[0] == ' ') {
prevline:
	    if (Comlinemode || ep->Line == 0) {
		i = ep->Column;
		break;
	    }
	    text_sync();
	    --ep->Line;
	    text_load();
	    ep->Column = Clen;
	    continue;
	}
	while (i && Current[i] != ' ')
	    --i;
	if (Current[i] == ' ')
	    ++i;
	break;
    }
    ep->Column = i;
    text_sync();
}


do_wright()
{
    register ubyte *ptr;
    register ED *ep = Ep;
    register int i;

    for (;;) {
	i = ep->Column;
	if (i == Clen)
	    goto nextline;
	while (i != Clen && Current[i] != ' ')  /* skip past current word */
	    ++i;
	while (i != Clen && Current[i] == ' ')  /* to beg. of next word   */
	    ++i;
	if (i == Clen) {
nextline:
	    if (Comlinemode || ep->Line == ep->Lines - 1) {
		i = ep->Column;
		break;
	    }
	    text_sync();
	    ++ep->Line;
	    text_load();
	    ep->Column = i = 0;
	    if (Current[0] != ' ')
		break;
	    continue;
	}
	break;
    }
    ep->Column = i;
    text_sync();
}


do_split()              /* split line in two at cursor pos */
{
    ubyte buf[256];
    register ED *ep = Ep;

    strcpy(buf, Current+ep->Column);
    Current[Clen = ep->Column] = '\0';
    text_sync();
    SetAPen(Rp, 0);
    if (Nsu == 0)
	RectFill(Rp, COL(0), ROW(ep->Line-ep->Topline), Xbase+Xpixs, ROW(ep->Line-ep->Topline+1)-1);
    SetAPen(Rp, 1);
    text_displayseg(ep->Line - ep->Topline, 1);
    do_downadd();
    do_insline();
    strcpy(Current, buf);
    Clen = strlen(Current);
    text_sync();
    text_displayseg(ep->Line - ep->Topline, 1);
    do_up();
}

do_join()
{
    register int i = Clen, j;
    register ED *ep = Ep;

    if (ep->Line + 1 < ep->Lines && strlen(ep->List[ep->Line+1])+i <= 253) {
	if (i && Current[i-1] != ' ')
	    Current[i++] = ' ';
	strcpy(Current+i, ep->List[ep->Line+1]);
	for (j = i; Current[j] == ' '; ++j);
	for (; i >= 0 && Current[i] == ' '; --i);
	if (j > i+2)
	    bmov(Current+j, Current+i+2, strlen(Current+j)+1);
	Clen = strlen(Current);
	text_sync();
	text_displayseg(ep->Line - ep->Topline, 1);
	do_down();
	do_deline();
	do_up();
	return(1);
    }
    return(0);
}

do_margin()
{
    Ep->Margin = atoi(av[1]);
}

do_wordwrap()
{
    register ED *ep = Ep;

    if (av[1][1] == 'n')
	ep->Wordwrap = 1;
    if (av[1][1] == 'f')
	ep->Wordwrap = 0;
    if (av[1][0] == 't')
	ep->Wordwrap = 1 - ep->Wordwrap;
    if (ep->Wordwrap)
	title("Wordwrap ON");
    else
	title("Wordwrap OFF");
}

/*
 * n == -1  :	force reformat entire paragraph
 * n ==  0  :	only until line equalizes (from text_write())
 *
 * What is a paragraph?   A paragraph ends whenever the left justification
 * gets larger, or on a blank line.
 */

do_reformat(n)
{
    register char *str;
    register ED *ep = Ep;
    int nlok, lnsc, fnst, fnsc;
    int column = ep->Column;
    int srow   = ep->Line;
    int crow   = srow;
    int erow   = srow;
    short dins = 0;	    /* relative insert lines/delete lines   */
    char moded = 0;	    /* any modifications done at all?	    */
    char checked = 0;	    /* for cursor positioning.		    */

    if (ep->Margin == 0)
	ep->Margin = 75;

    ++Nsu;
    for (;;) {
	str = (char *)ep->List[ep->Line+1];
	fnst = 0;
	fnsc = firstns(Current);
	nlok = (ep->Line + 1 < ep->Lines && fnsc >= (fnst=firstns(str)));
	if (nlok && str[0] == 0)
	    nlok = 0;
	lnsc = lastns(Current);
	if (lnsc < ep->Margin) {    /* space at end of line for marg-lnsc-2 letter word   */
	    if (nlok == 0)        /* but no more data to joinup   */
		break;		  /* done */
	    if (ep->Margin - lnsc - 2 >= wordlen(str+fnst)) {
		ep->Column = 0;
		Clen = lastns(Current);
		if (Current[Clen])
		    ++Clen;
		moded = 1;
		--dins;
		if (do_join())
		    continue;
		++dins;
		title("Error, Margin > 124");
		break;
	    }
	    if (n == 0)        /* if couldn't mod line, and text_write, don't update any more */
		break;
	    do_down();
	    erow = ep->Line;
	    continue;
	}
				/* no space, need to split	*/
				/* find start of prev word	*/
	for (;;) {
	    register int i = lnsc;
	    while (i && Current[i] != ' ')
		--i;
	    lnsc = i;
	    if (i >= ep->Margin) {
		while (i && Current[i] == ' ')
		    --i;
		if (i < ep->Margin)
		    break;
		lnsc = i;
		continue;
	    }
	    break;
	}
	if (lnsc) {             /* ok to split at word          */
	    ++lnsc;
	    ++dins;
	    ep->Column = lnsc;
	    do_split(); /* Split at point LNSC          */
	    do_down();          /* must insert proper amount?   */
	    {
		int indent = (nlok == 0) ? fnsc : fnst;
		if (!checked) {
		    checked = 1;
		    if (lnsc <= column) {   /* if split before cursor   */
			column = column - ep->Column + indent;
			++crow;
		    }
		}
		if (Clen + indent < 253) {
		    bmov(Current, Current + indent, strlen(Current)+1);
		    bset(Current, indent, ' ');
		    Clen += indent;
		}
	    }
	    erow = ep->Line;
	    continue;
	}
	if (n == 0)
	    break;
	do_down();
    }
    if (column < 0 || column > 200)
	column = 0;
    if (srow >= ep->Lines) {
	srow = ep->Lines - 1;
	goto ra;
    }
    if (dins || srow < ep->Topline || srow >= ep->Topline + Rows) {
ra:
	text_sync();
	--Nsu;
	ep->Line = crow;
	ep->Column = column;
	text_load();
	if (!text_sync())
	    text_redisplay();
    } else {
	text_sync();
	--Nsu;
	ep->Line = crow;
	ep->Column = column;
	text_load();
	if (erow != srow) {
	    if (!text_sync()) {
		++erow;
		if (erow - ep->Topline > Rows)
		    erow = ep->Topline + Rows;
		SetAPen(Rp, 0);
		RectFill(Rp, COL(0), ROW(srow - ep->Topline), Xbase+Xpixs, ROW(erow - ep->Topline)-1);
		SetAPen(Rp, 1);
		text_displayseg(srow - ep->Topline, erow - srow);
	    }
	} else {
	    text_sync();
	    if (moded)
		text_redisplaycurrline();
	}
    }
    if (column > Clen) {
	bset(Current+Clen, column - Clen, ' ');
	Current[column] = 0;
    }
    ep->Column = column;
}


do_tabstop()
{
    Ep->Tabstop = atoi(av[1]);
}


do_insertmode()
{
    register ED *ep = Ep;

    if (av[1][0]) {
	switch(av[1][1] & 0x1F) {
	case 'n'&0x1F:
	    ep->Insertmode = 1;
	    break;
	case 'f'&0x1F:
	    ep->Insertmode = 0;
	    break;
	case 'o'&0x1F:
	    ep->Insertmode = 1 - ep->Insertmode;
	    break;
	}
	if (ep->Insertmode)
	    title("Insert mode on");
	else
	    title("Insert mode off");
    }
}

do_insline()
{
    register ubyte *ptr;
    register ED *ep = Ep;

    ep->Modified = 1;
    text_sync();
    if (makeroom(32) && (ptr = allocb(1))) {
	bmovl(ep->List+ep->Line, ep->List+ep->Line+1,ep->Lines-ep->Line);
	ep->List[ep->Line] = ptr;
	*ptr = 0;
	++ep->Lines;
	if (BEp == ep) {
	    if (ep->Line < BSline)
		++BSline;
	    if (ep->Line <= BEline)
		++BEline;
	}
    } else {
	nomemory();
    }
    text_load();
    if (Nsu == 0)
	ScrollRaster(Rp,0,-Ysize, COL(0), ROW(ep->Line-ep->Topline), COL(Columns)-1, ROW(Rows)-1);
    text_displayseg(ep->Line - ep->Topline, 1);
}

do_deline()
{
    register int delline;
    register ED *ep = Ep;

    if (ep->Lines > 1) {
	ep->Modified = 1;
	text_sync();

	FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1);
	bmovl(ep->List+ep->Line+1, ep->List+ep->Line,ep->Lines-ep->Line-1);
	if (BEp == ep) {
	    if (ep->Line < BSline)
		--BSline;
	    if (ep->Line <= BEline)
		--BEline;
	}
	delline = ep->Line;
	if (ep->Line >= --ep->Lines) {
	    --ep->Line;
	    text_load();
	    if (ep->Line < ep->Topline) {
		if (Nsu == 0) {
		    ep->Topline = ep->Line - (Rows>>1);
		    if (ep->Topline < 0)
			ep->Topline = 0;
		    text_redisplay();
		}
		return(0);
	    }
	}
	text_load();
	if (Nsu == 0)
	    ScrollRaster(Rp,0,Ysize, COL(0), ROW(delline-ep->Topline), COL(Columns)-1, ROW(Rows)-1);
	text_displayseg(Rows-1, 1);
    } else {
	do_firstcolumn();
	do_remeol();
	ep->Modified = 0;
    }
}

do_chfilename()
{
    text_sync();
    strncpy(Ep->Name, av[1], 63);
    MForceTitle = 1;
}

do_edit()
{
    long xfi;
    long oldlock;
    long lines;
    ubyte buf[256];
    ubyte *ptr;
    char failed = 1;
    register ED *ep = Ep;

    text_sync();
    if (*av[0] == 'n') {        /* newfile or insfile   */
	if (ep->Modified && getyn("Delete modified Image?") == 0)
	    return(0);
	ep = uninit_init(ep);
	strncpy(ep->Name, av[1], 63);
    } else {
	ep->Modified = 1;
    }
    lines = ep->Lines;
    oldlock = CurrentDir(ep->dirlock);
    if (xfi = xfopen(av[1], "r", 4096)) {
	register int len;
	char oktitle = 1;

	title("Loading...");
	while ((len = xefgets(xfi, buf, 255)) >= 0) {
	    failed = 0;
	    if (makeroom(256) && (ptr = allocb(len+1))) {
		ep->List[ep->Lines++] = ptr;
		bmov(buf, ptr, len+1);
	    } else {
		set_window_params();
		nomemory();
		oktitle = 0;
		break;
	    }
	}
	set_window_params();
	if (oktitle)
	    title("OK");
    } else {
	title("File Not Found");
#if AREXX
	cmderr = CMD_FAILED;
#endif
    }
    xfclose(xfi);
    CurrentDir(oldlock);
    if (ep->Lines != 1 && lines == 1 && ep->List[0][0] == 0) {
	ep->Modified = 0;
	ep->Line = 0;
	FreeMem(ep->List[0], strlen(ep->List[0])+1);
	bmovl(ep->List+1, ep->List,--ep->Lines);
    } else {
	if (!failed && lines <= ep->Lines - 1) {
	    BEp = ep;
	    BSline = lines;
	    BEline = ep->Lines - 1;
	    do_bmove();
	}
    }
    set_window_params();
    text_load();
    text_redisplay();
}


static char blockmode;

do_bsave()
{
    blockmode = 1;
    do_saveas();
}

do_save()
{
    av[1] = Ep->Name;
    do_saveas();
}

do_savetabs()
{
    Savetabs = (av[1][0] && av[1][1] == 'n') ? 1 : 0;
}

do_saveas()
{
    long oldlock;
    long xfi;
    register long i;
    register short j, k;
    register ubyte *ptr, *bp;
    long xs, xe;
    ubyte buf[256];
    char bm;
    ED *ep;

    bm = blockmode;
    if (blockmode && blockok()) {
	xs = BSline;
	xe = BEline + 1;
	ep = BEp;
    } else {
	xs = 0;
	xe = Ep->Lines;
	ep = Ep;
    }
    blockmode = 0;
    text_sync();
    oldlock = CurrentDir(Ep->dirlock);
    if (Wbs && Wdisable == 0) {     /* Write out .info file */
	DISKOBJ sdo, *d;
	bzero(&sdo, sizeof(sdo));
	if ((d = GetDiskObject(av[1])) == NULL) {
	    if (getpath(Wbs->sm_ArgList[0].wa_Name, buf)) {
		sdo.do_Magic = WB_DISKMAGIC;
		sdo.do_Version = WB_DISKVERSION;
		makemygadget(&sdo.do_Gadget);
		sdo.do_Type = WBPROJECT;
		sdo.do_DefaultTool = (char *)buf;
		sdo.do_ToolTypes = NULL;
		sdo.do_CurrentX = NO_ICON_POSITION;
		sdo.do_CurrentY = NO_ICON_POSITION;
		sdo.do_DrawerData = NULL;
		sdo.do_ToolWindow = NULL;
		sdo.do_StackSize = 8192;
		PutDiskObject(av[1], &sdo);
	    }
	} else {
	    FreeDiskObject(d);
	}
    }
    if (xfi = xfopen(av[1], "w", 4096)) {
	title("Saving...");
	for (i = xs; i < xe; ++i) {
	    ptr = ep->List[i];
	    if (Savetabs) {
		for (bp = buf, j = 0; *ptr; ++ptr, ++bp, j = (j+1)&7) {
		    *bp = *ptr;
		    if (j == 7 && *bp == ' ' && *(bp-1) == ' ') {
			k = j;
			while (k-- >= 0 && *bp == ' ')
			    --bp;
			*++bp = 9;
		    } else {
			if (*bp == '\"' || *bp == '\'' || *bp == '\`' || *bp == '(')
			    break;
		    }
		}
		strcpy(bp, ptr);
		ptr = buf;
	    }
	    xfwrite(xfi, ptr, strlen(ptr));
	    if (xfwrite(xfi, "\n", 1)) {
		xfclose(xfi);
		goto err;
	    }
	}
	if (xfclose(xfi)) {
err:	    Abortcommand = 1;
	    title("WRITE FAILED!");
	} else {
	    ep->Modified &= bm;
	    title("OK");
	}
    } else {
	title("Unable to open write file");
	Abortcommand = 1;
    }
    CurrentDir(oldlock);
}

do_block()          /* block, unblock   */
{
    text_sync();

    switch(av[0][0]) {
    case 'b':
	if (BSline < 0) {
bstart:
	    BEp = Ep;
	    BSline = Ep->Line;
	    title("Block Begin");
	} else {
	    if (BEline > -1) {
		title("Block Already Marked");
		break;
	    }
	    if (BEp != Ep)
		goto bstart;
	    title("Block End");
	    BEline = Ep->Line;
	    if (BSline > BEline) {
		BEline = BSline;
		BSline = Ep->Line;
	    }
	    text_redrawblock(1);
	}
	break;
    case 'u':
	text_redrawblock(0);
	title ("Block Unmarked");
	break;
    }
}


blockok()
{
    if (BEp && BSline >= 0 && BSline <= BEline && BEline < BEp->Lines)
	return(1);
    BEp = NULL;
    BSline = BEline = -1;
    title("Block Not Specified");
    return(0);
}


do_bdelete()
{
    register long i, n;
    register ED *bep = BEp;
    register WIN *savewin = Ep->Win;

    if (blockok()) {
	text_switch(bep->Win);
	n = BEline - BSline + 1;
	if (bep->Line >= BSline && bep->Line <= BEline)
	    bep->Line = BSline;
	if (bep->Line > BEline)
	    bep->Line -= n;
	freelist(bep->List + BSline, BEline - BSline + 1);
	bmovl(bep->List+BEline+1,bep->List+BSline,(bep->Lines-BEline-1));
	bep->Lines -= n;
	bep->Modified = 1;
	if (bep->Line >= bep->Lines)
	    bep->Line = bep->Lines - 1;
	if (bep->Line < 0)
	    bep->Line = 0;
	if (bep->Lines == 0)
	    bep = uninit_init(bep);
	text_load();
	BEp = NULL;
	BSline = BEline = -1;
	if (!text_sync())
	    text_redisplay();
	text_switch(savewin);
    }
}

void
do_bcopy()
{
    register ubyte **list;
    register long lines, i;
    register ED *ep = Ep;

    text_sync();
    if (!blockok())
	return;
    if (ep == BEp && ep->Line > BSline && ep->Line <= BEline) {
	title("Cannot Move into self");
	return;
    }
    lines = BEline - BSline + 1;
    if (extend(ep, lines)) {
	if (list = (ubyte **)allocl(lines)) {
	    bmovl(BEp->List+BSline,list,lines);
	    bmovl(ep->List+ep->Line, ep->List+ep->Line+lines, ep->Lines-ep->Line);
	    for (i = 0; i < lines; ++i) {
		ubyte *str = allocb(strlen(list[i])+1);
		if (!str) {
		    nomemory();
		    FreeMem(list, lines * sizeof(char *));
		    freelist(ep->List + Ep->Line, i);
		    bmovl(ep->List+ep->Line+lines, ep->List+ep->Line, ep->Lines-ep->Line);
		    return;
		}
		strcpy(str, list[i]);
		ep->List[ep->Line+i] = str;
	    }
	    FreeMem(list, lines * sizeof(char *));
	}
    }
    if (ep == BEp && ep->Line <= BSline) {
	BSline += lines;
	BEline += lines;
    }
    ep->Modified = 1;
    ep->Lines += lines;
    text_load();
    if (!text_sync())
	text_redisplay();
}


void
do_bmove()
{
    register long lines;
    register ubyte **list;
    register ED *ep = Ep;

    text_sync();
    if (!blockok())
	return;
    if (BEp == ep && ep->Line >= BSline && ep->Line <= BEline) {
	title("Cannot Move into self");
	return;
    }
    lines = BEline - BSline + 1;
    if (!(list = (ubyte **)allocl(lines))) {
	nomemory();
	return;
    }
    BEp->Modified = ep->Modified = 1;
    bmovl(BEp->List + BSline, list, lines);
    if (ep == BEp) {
	if (ep->Line > BSline) {
	    bmovl(ep->List+BEline+1, ep->List+BSline, ep->Line-BEline-1);
	    bmovl(list, ep->List + ep->Line - lines, lines);
	} else {
	    bmovl(ep->List+ep->Line, ep->List+ep->Line+lines, BSline-ep->Line);
	    bmovl(list, ep->List + ep->Line, lines);
	}
    } else {
	WIN *savewin = ep->Win;
	if (extend(ep, lines)) {
	    bmovl(BEp->List+BEline+1, BEp->List+BSline, BEp->Lines-BEline-1);
	    bmovl(ep->List+ep->Line, ep->List+ep->Line+lines, ep->Lines-ep->Line);
	    bmovl(list, ep->List+ep->Line, lines);
	    ep->Lines += lines;
	    BEp->Lines -= lines;
	    if (BEp->Line >= BSline && BEp->Line <= BEline)
		BEp->Line = BSline - 1;
	    if (BEp->Line > BEline)
		BEp->Line -= lines;
	    if (BEp->Line < 0)
		BEp->Line = 0;
	    BSline = BEline = -1;
	    if (BEp->Lines == 0) {
		register ubyte *ptr = allocb(1);
		BEp->List[0] = ptr;
		*ptr = 0;
		++BEp->Lines;
	    }
	    text_load();
	    text_switch(BEp->Win);
	    BEp = NULL;
	    ep = Ep;
	    if (!ep->iconmode) {
		if (!text_sync())
		    text_redisplay();
	    }
	    text_switch(savewin);
	    ep = Ep;
	}
    }
    BSline = BEline = -1;
    BEp = NULL;
    FreeMem(list, lines * sizeof(char *));
    ep->Modified = 1;
    text_load();
    if (!text_sync())
	text_redisplay();
}


/*
 * IF condition trueaction, IFELSE condition trueaction falseaction
 *
 *  condition:	!condition NOT the specified condition.
 *		#	   toggle number is SET
 *		top	   top of file (on first line)
 *		bot	   end of file (on last line)
 *		left	   start of line (leftmost column)
 *		right	   end of line (nothing but spaces under and to the right)
 *		modified   text has been modified
 *		insert	   currently in insert mode
 *		y[<=>]#    cursor is (any OR combo of <,>,=) row #  (line numbers start at 1)
 *		x[<=>]#    cursor is (<,>,<=,>=,<>) column #        (columns start at 1)
 *			    <> means 'not equal'
 *
 *		cl	   char under cursor is lower case
 *		cu	   char under cursor is upper case
 *		ca	   char under cursor is alpha
 *		cn	   char under cursor is numeric
 *		cb	   char within selected block
 *		c[<=>]#    char under cursor is (combo of <,>,and =) #
 */

do_if()
{
    char haselse = (av[0][2] == 'e');
    char iswhile = (av[0][0] == 'w');
    char istrue, notop = 0;
    char c, cx, cc;
    ubyte *buf1, *buf2;
    register ubyte *ptr;
    register ED *ep = Ep;
    int i, cxn, cn;

    buf1 = (ubyte *)malloc(256);
    buf2 = (ubyte *)malloc(256);
    if (buf1 == NULL || buf2 == NULL) {
	if (buf1) free(buf1);
	if (buf2) free(buf2);
	title("No Memory!");
	return(0);
    }
    breakreset();
    ptr = av[1];
    if (*ptr == '!') {
	notop = 1;
	++ptr;
    }
    c = ptr[0];
    cn= atoi(ptr);
    cx= ptr[1];
    cxn=atoi(ptr+1);
    strcpy(buf1, av[2]);

loop:
    istrue = 0;
    i = 0;
    switch(c) {
    case 'x':
	i = ep->Column + 1;
    case 'y':
	if (!i)
	    i = ep->Line + 1;
conditional:
	{
	    register int j, n;
	    char any = 0;

	    for (j = 1; ptr[j] && (ptr[j]<'0'||ptr[j]>'9'); ++j);
	    n = atoi(ptr+j);
	    for (j = 1; ptr[j]; ++j) {
		switch(ptr[j]) {
		case '<':
		    any = 1;
		    if (i < n)
			istrue = 1;
		    break;
		case '=':
		    any = 1;
		    if (i == n)
			istrue = 1;
		    break;
		case '>':
		    any = 1;
		    if (i > n)
			istrue = 1;
		    break;
		}
	    }
	    if (!any && i == n)  /* default is equivalence   */
		istrue = 1;
	}
	break;
    case 't':
	istrue = ep->Line == 0;
	break;
    case 'b':
	istrue = ep->Line == ep->Lines-1;
	break;
    case 'l':
	istrue = ep->Column == 0;
	break;
    case 'r':
	istrue = ep->Column == Clen;
	break;
    case 'm':
	text_sync();
	istrue = ep->Modified != 0;
	break;
    case 'i':
	istrue = ep->Insertmode != 0;
	break;
    case 'c':
	cc = Current[ep->Column];
	switch(cx) {
	case 'b':
	    istrue = BEp == ep && ep->Line >= BSline && ep->Line <= BEline;
	    break;
	case 'l':
	    istrue = cc >= 'a' && cc <= 'z';
	    break;
	case 'u':
	    istrue = cc >= 'A' && cc <= 'Z';
	    break;
	case 'a':
	    istrue = (cc>='a'&&cc<='z')||(cc>='A'&&cc<='Z')||(cc>='0'&&cc<='9');
	    break;
	case 'n':
	    istrue = (cc >= '0' && cc <= '9');
	    break;
	default:		/* c[<=>]#  */
	    i = Current[ep->Column];
	    goto conditional;
	    break;
	}
	break;
    default:
	if (c >= '0' && c <= '9')
	    istrue = do_toggle(cn) != 0;
	else
	    title("bad conditional");
	break;
    }
    istrue ^= notop;
    if (istrue) {
	strcpy(buf2, buf1);     /* could be executed multiple times */
	if (do_command(buf2) == 0)
	    goto done;
	if (iswhile) {
	    if (breakcheck())
		Abortcommand = 1;
	    else
		goto loop;
	}
    } else {
	if (haselse) {          /* only executed once */
	    strcpy(buf2, av[3]);
	    do_command(buf2);
	}
    }
done:
    free(buf1);
    free(buf2);
}


/*
 * TOGGLE #, SETTOGGLE #, RESETTOGGLE #
 */

do_toggle(n)
{
    static char tg[MAXTOGGLE];
    register int i;

    if (n >= 0) {
	if (n >= MAXTOGGLE)
	    return(0);
	return(tg[n]);
    }
    i = atoi(av[1]);
    if (i >= 0 && i < MAXTOGGLE) {
	switch(av[0][0]) {
	case 't':
	    tg[i] = !tg[i];
	    break;
	case 's':
	    tg[i] = 1;
	    break;
	case 'r':
	    tg[i] = 0;
	    break;
	}
    }
}


do_tlate()
{
    register ubyte *ptr = av[1];
    register ED *ep = Ep;
    register char c = Current[ep->Column];

    if (c == 0)
	c = ' ';
    if (ptr[0] == '+')
	c += atoi(ptr+1);
    else
    if (ptr[0] == '-')
	c -= atoi(ptr+1);
    else
	c = atoi(ptr);
    if (c) {
	if (Current[ep->Column] == 0) {
	    Clen = ep->Column + 1;
	    Current[Clen] = 0;
	}
	Current[ep->Column] = c;
	if (Nsu == 0) {
	    movetocursor();
	    setpen(ep->Line);
	    Text(Rp, Current+ep->Column, 1);
	}
    }
}

/*
 *  BSOURCE
 *
 *  note that since the start and end lines are loaded immediately and the
 *  block unblock'd before execution starts, you can theoretically have
 *  another BSOURCE as part of this BSOURCE (but be carefull!).
 */

do_bsource()
{
    ubyte buf[256];
    register int i, sl, se;

    if (blockok()) {
	sl = BSline;
	se = BEline + 1;
	for (i = sl; BEp && i < se && i < BEp->Lines; ++i) {
	    text_sync();        /* make sure we are using latest text */
	    strcpy(buf, BEp->List[i]);
	    if (do_command(buf) == 0)
		break;
	}
	text_redrawblock(0);
    }
}

/*
 *  SCANF controlstring
 *
 *  The C scanf routine.  Only one variable, a string, is allowed in the
 *  control string.
 */

void
do_scanf()
{
    char buf[256];

    buf[0] = 0;
    sscanf(Current+Ep->Column,av[1],buf,buf,buf,buf,buf,buf,buf);
    if (String)
	free(String);
    String = (char *)malloc(strlen(buf)+1);
    strcpy(String,buf);
    title(String);
}

movetocursor()
{
    register ED *ep = Ep;
    Move(Rp, XTbase+(ep->Column-ep->Topcolumn)*Xsize, YTbase+(ep->Line-ep->Topline)*Ysize);
}

extend(ep, lines)
register ED *ep;
{
    register long extra = ep->Maxlines - ep->Lines;
    register ubyte **list;

    if (lines > extra) {
	lines += ep->Lines;
	if (list = (ubyte **)allocl(lines)) {
	    bmovl(ep->List, list, ep->Lines);
	    FreeMem(ep->List, sizeof(char *) * ep->Maxlines);
	    ep->Maxlines = lines;
	    ep->List = list;
	    return(1);
	}
	nomemory();
	return(0);
    }
    return(1);
}

makeroom(n)
{
    register ED *ep = Ep;
    if (ep->Lines >= ep->Maxlines)
	return(extend(ep, n));
    return(1);
}

freelist(list, n)
register char **list;
{
    while (n) {
	FreeMem(list[0], strlen(list[0])+1);
	++list;
	--n;
    }
}

\Rogue\Monster\
else
  echo "will not over write ./src/cmd2.c"
fi
if [ `wc -c ./src/cmd2.c | awk '{printf $1}'` -ne 23079 ]
then
echo `wc -c ./src/cmd2.c | awk '{print "Got " $1 ", Expected " 23079}'`
fi
echo "Finished archive 2 of 6"
# if you want to concatenate archives, remove anything after this line
exit
-- 
Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
Have five nice days.