Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!rutgers!ucla-cs!zen!ucbvax!s.cc.purdue.edu!dillon%cory.berkeley.edu
From: dillon%cory.berkeley.edu@berkeley.edu (Matt Dillon)
Newsgroups: comp.sources.amiga
Subject: DME V1.27 (sources part 1 of 2)
Message-ID: <383@s.cc.purdue.edu>
Date: Wed, 1-Jul-87 08:33:29 EDT
Article-I.D.: s.383
Posted: Wed Jul  1 08:33:29 1987
Date-Received: Sat, 11-Jul-87 01:31:46 EDT
Sender: doc@s.cc.purdue.edu
Reply-To: doc@s.cc.purdue.edu (Craig Norborg)
Distribution: world
Organization: Purdue University Computing Center
Lines: 1956
Approved: doc@s.cc.purdue.edu


	This is part 1 of 2 of the sources to dme.
#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# Xshar: Extended Shell Archiver.
# This is part  1 out of  2.
# This archive created: Wed Jul  1 07:25:23 1987
# By: Craig Norborg (Purdue University Computing Center)
#	Run the following text with /bin/sh to create:
#	command.c
#	globals.c
#	main.c
#	makefile
#	text1.c
cat << \SHAR_EOF > command.c

/*
 * COMMAND.C
 *
 *	(C)Copyright 1987 by Matthew Dillon, All Rights Reserved
 *
 * 'c                single character (typing)
 * `string'          string of characters w/ embedded `' allowed!
 *
 * name arg arg      command name. The arguments are interpreted as strings
 *		     for the command.
 *
 * Any string arguments not part of a command are considered to be typed
 * text.
 */

#include "defs.h"

extern char *breakout();

short ComLineMode;
char Abortcommand;

typedef struct {
   char *name;	  /* command name					*/
   short args;	  /* # of arguments					*/
   short sl;	  /* 1 if stays within bounds of the current line	*/
   int (*func)(); /* function						*/
} COMM;

extern int  do_map(),	do_unmap(), do_up(), do_down(), do_left(), do_right(),
	    do_return(), do_bs(), do_del(), do_esc(), do_downadd(),
	    do_lastcolumn(), do_firstcolumn(), do_edit(), do_tab(),
	    do_backtab(), do_save(), do_saveas(), do_deline(), do_insline(),
	    do_top(), do_bottom(), do_source(), do_firstnb(),
	    do_quit(), do_find(), do_page(), do_savetabs(),
	    do_split(), do_goto(), do_screentop(), do_screenbottom(),
	    do_join(), do_repeat(), do_tabstop(), do_insertmode(),
	    do_block(), do_bdelete(), do_bcopy(), do_bmove(), do_bsave(),
	    do_wleft(), do_wright(), do_remeol(), do_savemap(),
	    do_toggle(), do_if(), do_tlate(), do_bsource(),
	    do_findr(), do_findstr(), do_newwindow(),
	    do_windowparm(), do_resize(), do_margin(), do_wordwrap(),
	    do_reformat(), do_execute();

extern int do_iconify(), do_tomouse();


/*
 *  WLEFT/WRIGHT will check command line mode themselves, and thus can
 *  be marked sl=1 even though they can change the line number.
 *
 *  No more than 255 commands may exist unless you change the type of hindex[]
 *
 *  Command names MUST be sorted by their first character
 */

unsigned char hindex[26];   /*	alpha hash into table	*/

COMM Comm[] = {
    "back",          0, 1, do_bs,
    "backtab",       0, 1, do_backtab,
    "bcopy",         0, 0, do_bcopy,
    "bdelete",       0, 0, do_bdelete,
    "block",         0, 0, do_block,    /* checks com name for mode */
    "bmove",         0, 0, do_bmove,
    "bottom",        0, 0, do_bottom,
    "bs",            0, 1, do_bs,
    "bsave",         1, 0, do_bsave,
    "bsource",       0, 0, do_bsource,
    "del",           0, 1, do_del,
    "deline",        0, 0, do_deline,
    "down",          0, 0, do_down,
    "downadd",       0, 0, do_downadd,
    "esc",           0, 1, do_esc,
    "escimm",        1, 0, do_esc,
    "execute",       1, 0, do_execute,
    "find",          1, 0, do_find,     /* checks com name for mode */
    "findr",         2, 0, do_findr,    /* checks com name for mode */
    "findstr",       1, 1, do_findstr,  /* checks com name for mode */
    "first",         0, 1, do_firstcolumn,
    "firstnb",       0, 1, do_firstnb,
    "goto",          1, 0, do_goto,
    "height",        1, 1, do_windowparm,
    "iconify",       0, 0, do_iconify,
    "if",            2, 0, do_if,
    "ifelse",        3, 0, do_if,
    "insertmode",    1, 1, do_insertmode,
    "insfile",       1, 0, do_edit,
    "insline",       0, 0, do_insline,
    "join",          0, 0, do_join,
    "last",          0, 1, do_lastcolumn,
    "left",          0, 1, do_left,
    "leftedge",      1, 1, do_windowparm,
    "map",           2, 0, do_map,
    "margin",        1, 1, do_margin,
    "newfile",       1, 0, do_edit,     /* checks com name for mode */
    "newwindow",     0, 0, do_newwindow,
    "next",          0, 0, do_find,
    "nextr",         0, 0, do_findr,
    "pagedown",      0, 0, do_page,
    "pageset",       1, 0, do_page,
    "pageup",        0, 0, do_page,
    "prev",          0, 0, do_find,
    "prevr",         0, 0, do_findr,
    "quit",          0, 0, do_quit,
    "reformat",      0, 0, do_reformat,
    "remeol",        0, 1, do_remeol,
    "repeat",        2, 1, do_repeat,
    "repstr",        1, 1, do_findstr,
    "resettoggle",   1, 1, do_toggle,
    "resize",        2, 0, do_resize,
    "return",        0, 1, do_return,   /* special meaning in command line mode */
    "right",         0, 1, do_right,
    "saveas",        1, 0, do_saveas,
    "savemap",       1, 0, do_savemap,  /* checks com name for mode */
    "saveold",       0, 0, do_save,
    "savesmap",      1, 0, do_savemap,
    "savetabs",      1, 0, do_savetabs,
    "screenbottom",  0, 0, do_screenbottom,
    "screentop",     0, 0, do_screentop,
    "settoggle",     1, 1, do_toggle,
    "source",        1, 0, do_source,
    "split",         0, 0, do_split,
    "tab",           0, 1, do_tab,
    "tabstop",       1, 1, do_tabstop,
    "tlate",         1, 0, do_tlate,
    "toggle",        1, 1, do_toggle,
    "tomouse",       0, 0, do_tomouse,
    "top",           0, 0, do_top,
    "topedge",       1, 1, do_windowparm,
    "unblock",       0, 0, do_block,
    "unmap",         1, 0, do_unmap,
    "up",            0, 0, do_up,
    "while",         2, 0, do_if,
    "width",         1, 1, do_windowparm,
    "wleft",         0, 1, do_wleft,
    "wordwrap",      1, 1, do_wordwrap,
    "wright",        0, 1, do_wright,
    NULL, 0, 0, NULL
};

init_command()
{
    register short hi;
    register COMM *comm;


    hi = sizeof(Comm)/sizeof(Comm[0]) - 2;
    comm = Comm + hi;

    while (hi >= 0) {
	hindex[comm->name[0] - 'a'] = hi;
	--hi;
	--comm;
    }
}

do_command(str)
char *str;
{
    register char *arg;
    char quoted;
    register short i, j;
    static int level;

    if (++level > 20) {
	title("Recursion Too Deep!");
	--level;
	return(0);
    }
    while (arg = breakout(&str, "ed)) {
	if (quoted) {
	    text_write(arg);
	    continue;
	}
	for (i = 0; arg[i]; ++i) {
	    if (arg[i] >= 'A' && arg[i] <= 'Z')
		arg[i] += 'a' - 'A';
	}
	if (arg[0] >= 'a' && arg[0] <= 'z') {
	    register COMM *comm = &Comm[hindex[arg[0]-'a']];
	    for (; comm->name && comm->name[0] == arg[0]; ++comm) {
		if (strcmp(arg, comm->name) == 0) {
		    av[0] = (u_char *)comm->name;
		    for (j = 1; j <= comm->args; ++j) {
			av[j] = (u_char *)breakout(&str, "ed);
			if (!av[j]) {
			    title("Bad argument");
			    --level;
			    return(0);
			}
		    }
		    if (comm->sl || !ComLineMode)
			(*comm->func)(-1);
		    if (Abortcommand)
			goto fail;
		    goto loop;
		}
	    }
	}
	/* Command not found, check for macro	*/

	{
	    char *str;
	    int ret;
	    str = keyspectomacro(arg);
	    if (str) {
		str = (char *)strcpy(malloc(strlen(str)+1), str);
		ret = do_command(str);
		free(str);
		if (ret)
		    goto loop;
		goto fail;
	    }
	}

	title("Unknown Command");
fail:
	--level;
	return(0);
loop:
	;
    }
    --level;
    return(1);
}


do_source()
{
    char buf[256];
    long fi;
    register short i;

    if (fi = xopen(av[1], "r", 256)) {
	while (xgets(fi, buf, 255)) {
	    for (i = 0; buf[i]; ++i) {
		if (buf[i] == 9)
		    buf[i] = ' ';
	    }
	    do_command(buf);
	}
	xclose(fi);
    } else {
	if (av[0])
	    title("File not found");
    }
}


do_quit()
{
    extern char Quitflag;

    Quitflag = 1;
}

do_execute()
{
    Execute(av[1], 0, 0);
}

/*
 * repeat X command
 *
 * Since repeat takes up 512+ stack, it should not be nested more than
 * twice.
 *
 * (if X is not a number it can be abbr. with 2 chars)
 *
 * X =	N     -number of repeats
 *	line  -current line # (lines begin at 1)
 *	lbot  -#lines to the bottom, inc. current
 *	cleft -column # (columns begin at 0)
 *		(thus is also chars to the left)
 *	cright-#chars to eol, including current char
 *	tr    -#char positions to get to next tab stop
 *	tl    -#char positions to get to next backtab stop
 */

#define SC(a,b) ((a)<<8|(b))

do_repeat()
{
    u_char *ptr = av[1];
    char buf1[256];
    char buf2[256];
    unsigned long n;

    breakreset();
    strcpy(buf1, av[2]);
    switch((ptr[0]<<8)+ptr[1]) {
    case SC('l','i'):
	n = text_lineno();
	break;
    case SC('l','b'):
	n = text_lines() - text_lineno() + 1;
	break;
    case SC('c','l'):
	n = text_colno();
	break;
    case SC('c','r'):
	n = text_cols() - text_colno();
	break;
    case SC('t','r'):
	n = text_tabsize()-(text_colno() % text_tabsize());
	break;
    case SC('t','l'):
	n = text_colno() % text_tabsize();
	if (n == 0)
	    n = text_tabsize();
	break;
    default:
	n = atoi(av[1]);
	break;
    }
    while (n > 0) {
	strcpy(buf2, buf1);
	if (do_command(buf2) == 0 || breakcheck()) {
	    Abortcommand = 1;
	    break;
	}
	--n;
    }
}


char *
breakout(ptr, quoted)
register char **ptr;
char *quoted;
{
    register char *str = *ptr;
    register char *base = str;

    *quoted = 0;
    while (*str == ' ')
	++str;
    if (!*str)
	return(NULL);
    if (*str == '\'') {
	if (str[1]) {
	    *quoted = 1;
	    base = str + 1;
	    if (str[2])
		++str;
	    *str = '\0';
	    *ptr = str;
	    return(base);
	}
	return(NULL);
    }
    if (*str == '`') {
	short count = 1;
	base = ++str;
	while (*str && count) {
	    if (*str == '`')
		++count;
	    if (*str == '\'')
		--count;
	    ++str;
	}
	if (count == 0) {
	    --str;
	    *quoted = 1;
	    *str = '\0';
	    *ptr = str + 1;
	    return(base);
	}
    }
    base = str;
    while (*str && *str != ' ')
	++str;
    if (*str) {
	*str = '\0';
	*ptr = str + 1;
	return(base);
    }
    *ptr = str;
    return(base);
}


SHAR_EOF
cat << \SHAR_EOF > globals.c

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

#include "defs.h"

#define TU	    titleupdate = 1
#define nomemory()  {memoryfail = 1; TU;}

ED E, *Ep;			/* Current File */
ED *Base;			/* doubly linked list of Files	*/

char Nsu;
char Savetabs;
char titleupdate;
char memoryfail;
u_char Current[256];
short Clen;


SHAR_EOF
cat << \SHAR_EOF > main.c

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

#include "defs.h"

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


NW Nw = {
   0, 1, 640, 199, -1, -1,
   IDCMPFLAGS,
   ACTIVATE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|RMBTRAP,
   NULL, NULL, (u_char *)"   WAIT   ",
   NULL, NULL,
   32, 32, -1, -1,
   WBENCHSCREEN
};

short Sharedrefs;
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;

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

int Enable_Abort;

extern ED E, *Ep, *Base;
extern char memoryfail;
extern WIN *opensharedwindow();
extern IMESS *GetMsg();

static char *Ffile;

main(mac, mav)
char *mav[];
{
    register IMESS *im;
    register WIN *win;
    char nf, ni;	    /* # files on command line	*/
    char notdone;
    char iawm = 0;
    char dontwait = 0;
    short i;
    short Code;

    init_command();
    Nwwidth = Nw.Width;
    Nwheight= Nw.Height;
    Nwtopedge=Nw.TopEdge;
    Nwleftedge=Nw.LeftEdge;
    Enable_Abort = 0;
    if (!openlibs(INTUITION_LIB|GRAPHICS_LIB))
	exiterr("cannot open intuition or graphics library");
    if (mac == 0) {
	long oldlock;
	Wdisable = 0;
	Wbs = (WBS *)mav;
	if (!openlibs(ICON_LIB))
	    exiterr("unable to open icon library");
	oldlock = CurrentDir(Wbs->sm_ArgList[0].wa_Lock);   /* tool */
	Do = GetDiskObject(Wbs->sm_ArgList[0].wa_Name);
	CurrentDir(oldlock);
	if (Do == NULL)
	    exiterr("unable to get disk object");
	mac = 99;
    }

    resethash();

    if (Do) {
	ops(Do->do_ToolTypes, 1);
	nf = Wbs->sm_NumArgs - 1;
	E.dirlock = 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;
	long oldlock;
	if (Wbs) {
	    if (i > nf)
		break;
	    str = Wbs->sm_ArgList[i].wa_Name;
	    oldlock = CurrentDir(Wbs->sm_ArgList[i].wa_Lock);
	    if (dso = GetDiskObject(Wbs->sm_ArgList[i].wa_Name)) {
		ops(dso->do_ToolTypes, 1);
		FreeDiskObject(dso);
	    }
	    E.dirlock = CurrentDir(oldlock);
	} else {
	    str = mav[i];
	    if (*str == '-')
		continue;
	}
	do_newwindow(nf > 1, ni * 10);
	++ni;
	av[0] = (u_char *)"newfile";
	av[1] = (u_char *)str;
	do_edit();
	MForceTitle = 1;
	window_title();
    }
    if (i == 1) 		    /* no files to edit */
	do_newwindow(nf > 1, ni * 10);

    mountrequest(0);
    av[0] = NULL;
    av[1] = (u_char *)"s:.edrc";
    do_source();
    av[0] = NULL;
    av[1] = (u_char *)((Ffile) ? Ffile : ".edrc");
    do_source();
    mountrequest(1);
    title("DME V1.27 (c)CopyRight 1987 Matthew Dillon,  All Rights Reserved                  ");
    text_titleupdate();
loop:
    if (!E.iconmode)
	text_cursor(1);
    for (notdone = 1; !Quitflag && notdone;) {
	char mmove = 0;
	short mqual;

	if (!E.iconmode)
	    window_title();
	if (dontwait)
	    --dontwait;
	else
	    WaitPort(Win->UserPort);
	while (im = (IMESS *)GetMsg(Win->UserPort)) {
	    Abortcommand = 0;
	    Code = im->Code;
	    if (im->IDCMPWindow != Win) {
		Overide = 0;
		if (ComLineMode)
		    escapecomlinemode();
		text_sync();
		MShowTitle = 0;
		if (!E.iconmode)
		    window_title();
		if (text_switch(im->IDCMPWindow) == 0) {
		    ReplyMsg(im);
		    continue;
		}
		if (!E.iconmode) {
		    set_window_params();
		    window_title();
		}
	    }
	    Mx = im->MouseX;
	    My = im->MouseY;
	    switch(im->Class) {
	    case NEWSIZE:
		if (!E.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 (E.iconmode || iawm) {
			uniconify();
			break;
		    }
		    ReportMouse(-1, Win);
		    uniconify();
		    text_cursor(0);
		    keyctl(im->Code, im->Qualifier);
		    text_cursor(1);
		    break;
		case SELECTUP:
		case MENUUP:
		    ReportMouse(0, Win);
		    break;
		}
		break;
	    case RAWKEY:
		if (E.iconmode) {
		    uniconify();
		    break;
		}
		text_cursor(0);
		keyctl(im->Code, im->Qualifier);
		text_cursor(1);
		break;
	    case CLOSEWINDOW:
		if (ComLineMode)
		    escapecomlinemode();
		text_sync();
		notdone = 0;
		break;
	    case ACTIVEWINDOW:
		if (!E.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(QMOVE, mqual);
	    text_cursor(1);
	}
	closesharedwindow(NULL);
    }
boom:
    if (E.Modified && !Overide) {
	uniconify();
	Overide = 1;
	SetWindowTitles(Win, "*** File has been modified ***", NULL);
	Quitflag = 0;
	goto loop;
    }
    SetWindowTitles(Win, "", -1);
    text_uninit();			/* uninitialize text portion	*/
    closesharedwindow(Win);
    if (Base) {
	Quitflag = 0;
	Win = E.Win;			/* make arbitrary other window act. */
	Rp = Win->RPort;
	if (!E.iconmode)
	    set_window_params();
	text_load();
	MShowTitle = 0;
	goto loop;
    }
    closesharedwindow(NULL);
    if (Do)
	FreeDiskObject(Do);
    closelibs(-1);
    dealloc_hash();
}

do_iconify()
{
    if (!ComLineMode)
	iconify();
}

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

iconify()
{
    if (!E.iconmode) {
	E.Winx	    = Win->LeftEdge;
	E.Winy	    = Win->TopEdge;
	E.Winwidth  = Win->Width;
	E.Winheight = Win->Height;
	Nw.Height = 10;
	Nw.Width  = 20 + 5*8 + strlen(E.Name)*8;
	Nw.LeftEdge= E.IWinx;
	Nw.TopEdge = E.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);
	Nw.Flags |= BORDERLESS;
	sprintf(Ep->Wtitle, "%s %s    ", E.Name, ((E.Modified) ? "(mod)":""));
	closesharedwindow(Win);
	Win = E.Win = Ep->Win = opensharedwindow(&Nw);
	Nw.Flags |= WINDOWSIZING|WINDOWDEPTH;
	Nw.Flags &= ~BORDERLESS;
	Rp = Win->RPort;
    }
    E.iconmode = 1;
}

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


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

    if (SizeOveride)
	msadj = 0;
    if (Ep)
	text_sync();
    Nw.Title = (u_char *)"    OK    ";
    Nw.Width = Nwwidth;
    Nw.Height= Nwheight;
    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);
    Nw.Flags |= ACTIVATE;
    if (win) {
	Win = win;			/* set new window   */
	Rp = Win->RPort;
	text_init();			/* initialize	    */
	text_load();
	set_window_params();
	if (makesmall != -1)		/* if deltaheight valid */
	    E.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);
	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    = (u_char *)text;
    pos->LeftEdge = AUTOLEFTEDGE;
    pos->TopEdge = AUTOTOPEDGE;
    pos->IText = (u_char *)"OK";
    neg->LeftEdge = AUTOLEFTEDGE;
    neg->TopEdge = AUTOTOPEDGE;
    neg->IText = (u_char *)"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);
    MShowTitle = 1;
}

window_title()
{
    static char cmodified;
    int len;
    char *mod;

    if (memoryfail) {
	SetWindowTitles(Win, " -- NO MEMORY -- ", -1);
	text_redisplay();
	memoryfail = 0;
	return(0);
    }
    if (MForceTitle) {
	cmodified = -1;
	MShowTitle = 0;
	MForceTitle = 0;
    }
    if (MShowTitle) {
	MShowTitle = 0;
	return(0);
    }
    if (text_titleupdate() || cmodified != E.Modified) {
	cmodified = E.Modified;
	mod = (E.Modified) ? " (modified)" : "";
	sprintf(Ep->Wtitle, "%3ld/%-3ld %s%s ", text_lineno(), text_lines(), 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;
	}
	SetWindowTitles(Win, Ep->Wtitle, -1);
    }
}

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())
	puts(str);
    exit(1);
}

breakcheck()
{
   if (SetSignal(0,0) & SIGBREAKF_CTRL_C)
      return (1);
   else
      return (0);
}

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

/*
 *  leftedge n
 *  topedge  n
 *  width    n
 *  height   n
 */

do_windowparm()
{
    switch(av[0][0]) {
    case 'l':
	Nwleftedge = atoi(av[1]);
	break;
    case 't':
	Nwtopedge = atoi(av[1]);
	break;
    case 'w':
	Nwwidth = atoi(av[1]);
	break;
    case 'h':
	Nwheight = atoi(av[1]);
	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);
}



SHAR_EOF
cat << \SHAR_EOF > makefile

#   Note:  In terms of compiling, if you do not have my latest
#   support library you may have to do some hacking to get the
#   code to link

CFLAGS= +L +Ivd0:include/symbols.m
OBJS= globals.o command.o keyboard.o main.o text1.o text2.o subs.o

c.o:
    cc $(CFLAGS) -o $@ $*.c

all: $(OBJS)
    ln +Q $(OBJS) -lmyl32 -lc32 -O c:dme

arc:
    -delete ram:dme.arc
    arc a ram:dme.arc dme.doc TODO c:dme

src:
    -delete ram:dmesrc.arc
    arc a ram:dmesrc makefile defs.h globals.c command.c keyboard.c main.c text1.c text2.c subs.c

SHAR_EOF
cat << \SHAR_EOF > text1.c

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

#include "defs.h"

#define TU	    titleupdate = 1
#define nomemory()  {memoryfail = 1; TU;}

text_init()
{
    register ED *e;
    long dirlock;

    text_switch(NULL);
    dirlock = E.dirlock;
    e = (ED *)MAllocate(sizeof(ED));
    if (e == NULL)
	return(0);
    bzero(&E, sizeof(E));
    E.Win = Win;
    if (Ep) {
	E.Insertmode = Ep->Insertmode;
	E.Tabstop    = Ep->Tabstop;
	E.Wordwrap   = Ep->Wordwrap;
    } else {
	E.Insertmode = 1;
	E.Tabstop = 4;
    }
    E.Lines = 1;
    E.Maxlines = 32;
    E.List = (u_char **)MAllocate(sizeof(char *) * E.Maxlines);
    E.List[0] = MAllocate(1);
    E.List[0][0] = Current[0] = Clen = 0;
    E.BSline = E.BEline = -1;
    E.IWiny = 16;
    E.dirlock = dirlock;	/* workbench support	*/
    *e = E;
    llink(&Base, e);
    strcpy(E.Name, "ram:unnamed");
    Ep = e;
    text_cursor(1);
    return(1);
}


text_switch(win)
WIN *win;
{
    register ED *e;
    register ED *next, **prev;

    if (Ep) {
	text_sync();
	E.next = Ep->next;
	E.prev = Ep->prev;
	strcpy(E.Wtitle, Ep->Wtitle);
	*Ep = E;
    }
    if (win) {
	for (e = Base; e; e = e->next) {
	    if (e->Win == win) {
		Ep = e;
		Win = win;
		Rp = Win->RPort;
		E = *e;
		text_load();
		return(1);
	    }
	}
	return(0);
    }
}


text_sync()
{
    char redraw = 0;
    short len;
    u_char *ptr;

    for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
	Current[len] = '\0';
    Clen = len + 1;
    if (!ComLineMode) {
	if (strlen(E.List[E.Line]) != Clen) {
	    if (ptr = MAllocate(Clen+1)) {
		E.Modified = 1;
		FreeMem(E.List[E.Line], strlen(E.List[E.Line])+1);
		E.List[E.Line] = ptr;
	    } else {
		nomemory();
		strcpy(Current, E.List[E.Line]);
		Clen = strlen(Current);
	    }
	} else {
	    if (strcmp(E.List[E.Line], Current))
		E.Modified = 1;
	}
	strcpy(E.List[E.Line], Current);
    }
    if (Nsu == 0) {
	if (E.Column - E.Topcolumn >= Columns || E.Column < E.Topcolumn) {
	    redraw = 1;
	    E.Topcolumn = E.Column - (Columns>>1);
	    if (E.Topcolumn < 0)
		E.Topcolumn = 0;
	}
	if (E.Line - E.Topline >= Rows || E.Line < E.Topline) {
	    redraw = 1;
	    E.Topline = E.Line - (Rows>>1);
	    if (E.Topline < 0)
		E.Topline = 0;
	}
    }
    while (E.Column > Clen)
	Current[Clen++] = ' ';
    Current[Clen] = '\0';
    if (redraw)
	text_redisplay();
    return((int)redraw);
}

text_load()
{
    if (ComLineMode)
	return(0);
    strcpy(Current, E.List[E.Line]);
    Clen = strlen(Current);
    while (E.Column > Clen)
	Current[Clen++] = ' ';
    Current[Clen] = '\0';
}

text_titleupdate()
{
    int r = titleupdate;

    titleupdate = 0;
    return(r);
}

text_lineno()
{
    return(E.Line + 1);
}

text_lines()
{
    return(E.Lines);
}

text_colno()
{
    return(E.Column);
}

text_cols()
{
    return((int)Clen);
}

text_imode()
{
    return(E.Insertmode);
}

text_tabsize()
{
    return((int)E.Tabstop);
}

u_char *
text_name()
{
    return(E.Name);
}


text_uninit()
{
    register int i;
    register ED *e;

    for (i = 0; i < E.Lines; ++i)
	FreeMem(E.List[i], strlen(E.List[i])+1);
    FreeMem(E.List, E.Maxlines * sizeof(char *));

    lunlink(Ep);
    FreeMem(Ep, sizeof(ED));
    if (Base) {
	E = *Base;
	Ep= Base;
	text_load();
    } else {
	Ep = NULL;
    }
}

inversemode(n)
{
    if (n) {
	SetAPen(Rp, 3);
	SetDrMd(Rp, JAM2|INVERSVID);
    } else {
	SetAPen(Rp, 1);
	SetDrMd(Rp, JAM2);
    }
}

text_cursor(n)
{
    movetocursor();
    inversemode(n);
    if (Current[E.Column])
	Text(Rp, Current+E.Column, 1);
    else
	Text(Rp, " ", 1);
    inversemode(0);
}


text_position(col, row)
{
    TU;
    text_sync();
    if (col == 0)
	col = -1;
    E.Column = E.Topcolumn + col;
    if (E.Column > 254)
	E.Column = 254;
    if (E.Column < 0)
	E.Column = 0;
    E.Line = E.Topline + row;
    if (E.Line >= E.Lines)
	E.Line = E.Lines - 1;
    if (E.Line < 0)
	E.Line = 0;
    text_load();
    text_sync();
}


text_displayseg(start, n)
{
    register short i, c;
    register u_char *ptr;
    char ib;

    if (Nsu)
	return(0);
    for (i = start; i < start+n && E.Topline + i < E.Lines; ++i) {
	if (ComLineMode) {
	    if (E.Topline + i != E.Line)
		continue;
	    ptr = Current;
	} else {
	    ptr = E.List[E.Topline + i];
	}
	for (c = E.Topcolumn; c && *ptr; ++ptr, --c);
	c = strlen(ptr);
	if (c) {
	    Move(Rp, COLT(0), ROWT(i));
	    Text(Rp, ptr, (c > Columns) ? Columns : c);
	}
    }
}

text_redisplay()
{
    if (Nsu)
	return(0);
    SetAPen(Rp, 0);
    if (ComLineMode)
	RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
    else
	RectFill(Rp, Xbase, Ybase, Xbase + Xpixs, Ybase + Ypixs);
    SetAPen(Rp, 1);
    text_displayseg(0,Rows);
}

text_redisplaycurrline()
{
    int row = E.Line - E.Topline;

    if (Nsu)
	return(0);
    SetAPen(Rp, 0);
    RectFill(Rp, COL(0), ROW(row), Xbase+Xpixs, ROW(row+1)-1);
    SetAPen(Rp, 1);
    text_displayseg(row, 1);
}

text_write(str)
u_char *str;
{
    short len = strlen(str);
    short i;

    if (Clen + len >= 255) {
	text_sync();
	text_load();
    }
    if (E.Insertmode == 0) {
	i = len;
	if (E.Column + len < 255) {
	    bmov(str, Current + E.Column, len);
	    if (E.Column + len >= Clen)
		Clen = E.Column + len;
	    Current[Clen] = 0;
	    goto bin;
	}
	goto ok;
    }
    if (Clen + len < 255) {
	bmov(Current + E.Column, Current + E.Column + len, Clen+1-E.Column);
	bmov(str, Current + E.Column, len);
	Clen += len;
	ScrollRaster(Rp, -len * Xsize, 0 ,
		COL(E.Column - E.Topcolumn), ROW(E.Line - E.Topline),
		COL(Columns) - 1, ROW(E.Line - E.Topline + 1) - 1
	);
	i = (E.Column - E.Topcolumn + len > Columns) ? Columns - E.Column + E.Topcolumn : len;
bin:
	Move(Rp, COLT(E.Column - E.Topcolumn), ROWT(E.Line - E.Topline));
	Text(Rp, str, i);
	E.Column += len;
	if (E.Column - E.Topcolumn >= Columns)
	    text_sync();
    }
ok:
    if (ComLineMode == 0 && E.Wordwrap)
	do_reformat(0);
}


do_up()
{
    if (E.Line) {
	TU;
	text_sync();
	--E.Line;
	text_load();
	if (E.Line < E.Topline) {
	    if (Nsu == 0) {
		ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
		--E.Topline;
		text_displayseg(0, 1);
	    }
	}
    } else {
	Abortcommand = 1;
    }
}

do_down()
{
    if (E.Line + 1 < E.Lines) {
	TU;
	text_sync();
	++E.Line;
	text_load();
	if (E.Line - E.Topline >= Rows) {
	    if (Nsu == 0) {
		ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
		++E.Topline;
		text_displayseg(Rows-1, 1);
	    }
	}
    } else {
	Abortcommand = 1;
    }
}

/*
 *  PAGEUP
 *  PAGEDOWN
 *  PAGESET n	(n = 0 to 100 for percentage of #rows to scroll, minimum 1)
 *		can be > 100.
 */

do_page()
{
    register int n, multiplier = 1;
    static short pctg = 80;

    switch(av[0][4]) {
    case 'u':
	multiplier = -1;
    case 'd':
	n = multiplier * Rows * pctg / 100;
	if (!n)
	    n = multiplier;
	if (n > 0 && E.Topline >= E.Lines - Rows)
	    return(0);
	text_sync();
	TU;
	E.Line += n;
	E.Topline += n;
	if (E.Line >= E.Lines)
	    E.Line = E.Lines - 1;
	if (E.Line < 0)
	    E.Line = 0;
	if (E.Topline >= E.Lines)
	    E.Topline = E.Lines - Rows - 1;
	if (E.Topline < 0)
	    E.Topline = 0;
	text_load();
	if (!text_sync())
	    text_redisplay();
	break;
    case 's':
	pctg = atoi(av[1]);
	break;
    }
}


do_downadd()
{
    u_char *ptr;

    if (E.Line + 1 == E.Lines) {
	E.Modified = 1;
	if (makeroom(32) && (ptr = MAllocate(1))) {
	    E.List[E.Lines] = ptr;
	    *ptr = 0;
	    ++E.Lines;
	} else {
	    nomemory();
	}
    }
    do_down();
}


do_left()
{
    if (E.Column) {
	--E.Column;
	if (E.Column < E.Topcolumn)
	    text_sync();
    } else {
	Abortcommand = 1;
    }
}

do_right()
{
    if (E.Column != 254) {
	if (Current[E.Column] == 0) {
	    Current[E.Column] = ' ';
	    Current[E.Column+1]= '\0';
	    ++Clen;
	}
	++E.Column;
	if (E.Column - E.Topcolumn >= Columns)
	    text_sync();
    } else {
	Abortcommand = 1;
    }
}

do_tab()
{
    register short n;

    for (n = E.Tabstop-(E.Column % E.Tabstop); n > 0; --n)
	do_right();
}

do_backtab()
{
    register short n;

    n = E.Column % E.Tabstop;
    if (!n)
	n = E.Tabstop;
    for (; n > 0; --n)
	do_left();
}

do_return()
{
    u_char buf[256];

    if (ComLineMode) {
	strcpy(buf, Current);
	escapecomlinemode();
	do_command(buf);
    } else {
	E.Column = 0;
	text_sync();
	do_downadd();
    }
}

do_bs()
{
    if (E.Column) {
	bmov(Current + E.Column, Current + E.Column - 1, Clen - E.Column + 1);
	--E.Column;
	--Clen;
	if (E.Column < E.Topcolumn) {
	    text_sync();
	} else {
	    ScrollRaster(Rp, Xsize, 0,
		COL(E.Column - E.Topcolumn),
		ROW(E.Line   - E.Topline),
		COL(Columns)-1,
		ROW(E.Line - E.Topline + 1)-1
	    );
	    if (Clen >= E.Topcolumn + Columns) {
		Move(Rp, COLT(Columns-1), ROWT(E.Line - E.Topline));
		Text(Rp, Current + E.Topcolumn + Columns - 1, 1);
	    }
	}
	if (ComLineMode == 0 && E.Wordwrap)
	    do_reformat(0);
    } else {
	Abortcommand = 1;
    }
}


/*
 * esc, escimm
 */

int Savetopline, Savecolumn, Savetopcolumn;

do_esc()
{
    if (ComLineMode)
	return(escapecomlinemode());
    text_sync();
    if (av[0][3] == 'i')
	strcpy(Current, av[1]);
    else
	Current[0] = 0;
    Clen = strlen(Current);
    ComLineMode = 1;
    returnoveride(1);
    Savetopline = E.Topline;
    Savecolumn	= E.Column;
    Savetopcolumn = E.Topcolumn;
    E.Column	= Clen;
    E.Topcolumn = 0;
    E.Topline	= E.Line - Rows + 1;
    SetAPen(Rp, 0);
    RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
    SetAPen(Rp, 1);
    Move(Rp, COL(0), ROW(Rows-1) - 1);
    Draw(Rp, Xbase + Xpixs, ROW(Rows-1) - 1);
    text_displayseg(Rows-1,1);
}


escapecomlinemode()
{
    if (ComLineMode) {
	ComLineMode = 0;
	returnoveride(0);
	E.Topline = Savetopline;
	E.Column  = Savecolumn;
	E.Topcolumn = Savetopcolumn;
	text_load();
	SetAPen(Rp, 0);
	RectFill(Rp, COL(0), ROW(Rows-1)-1, Xbase+Xpixs, Ybase+Ypixs);
	SetAPen(Rp, 1);
	text_displayseg(Rows-2,2);
    }
}


do_del()
{
    if (Current[E.Column]) {
	bmov(Current + E.Column + 1, Current + E.Column, Clen - E.Column);
	--Clen;
	ScrollRaster(Rp, Xsize, 0,
	    COL(E.Column - E.Topcolumn),
	    ROW(E.Line - E.Topline),
	    COL(Columns)-1,
	    ROW(E.Line - E.Topline + 1) - 1
	);
	if (Clen >= E.Topcolumn + Columns) {
	    Move(Rp, COLT(Columns-1), ROWT(E.Line-E.Topline));
	    Text(Rp, Current+E.Topcolumn+Columns-1, 1);
	}
	if (ComLineMode == 0 && E.Wordwrap)
	    do_reformat(0);
    }
}

do_top()
{
    text_sync();
    E.Line = 0;
    TU;
    text_load();
    text_sync();
}

do_bottom()
{
    text_sync();
    E.Line = E.Lines - 1;
    TU;
    text_load();
    text_sync();
}

do_firstcolumn()
{
    if (E.Column) {
	E.Column = 0;
	text_sync();
    }
}

do_firstnb()
{
    for (E.Column = 0; Current[E.Column] == ' '; ++E.Column);
    if (Current[E.Column] == 0)
	E.Column = 0;
    text_sync();
}

do_lastcolumn()
{
    short i;

    text_sync();
    i = (ComLineMode) ? Clen : strlen(E.List[E.Line]);
    if (i != E.Column) {
	E.Column = i;
	text_sync();
    }
}

/*
 * GOTO [+/-]N
 * GOTO BLOCK	start of block
 * GOTO START	start of block
 * GOTO END	end of block
 */

do_goto()
{
    register short n, i;
    register u_char *ptr = av[1];

    i = 0;
    n = -1;

    switch(*ptr) {
    case 'b':
    case 's':
    case 'B':
    case 'S':
	n = E.BSline;
	break;
    case 'e':
    case 'E':
	n = E.BEline;
	break;
    case '+':
	i = 1;
    case '-':
	n = E.Line;
    default:
	n += atoi(ptr+i);
    }
    if (n >= E.Lines)
	n = E.Lines - 1;
    if (n < 0)
	n = 0;
    text_sync();
    E.Line = n;
    TU;
    text_load();
    text_sync();
}

do_screentop()
{
    text_sync();
    TU;
    E.Line = E.Topline;
    text_load();
    text_sync();
}

do_screenbottom()
{
    text_sync();
    TU;
    E.Line = E.Topline + Rows - 1;
    if (E.Line < 0 || E.Line >= E.Lines)
	E.Line = E.Lines - 1;
    text_load();
    text_sync();
}

static u_char Fstr[256];
static u_char Rstr[256];
static short Srch_sign;
static char Doreplace;

/*
 * findstr, repstr
 */

do_findstr()
{
    if (av[0][0] == 'f')
	strcpy(Fstr, av[1]);
    else
	strcpy(Rstr, av[1]);
}

/*
 * findr, nextr, prevr
 */

do_findr()
{
    Doreplace = 1;
    Srch_sign = 1;
    switch(av[0][0]) {
    case 'f':
	strcpy(Fstr, av[1]);
	strcpy(Rstr, av[2]);
	break;
    case 'p':
	Srch_sign = -1;
	break;
    }
    search_operation();
}

/*
 * find, next, prev
 */

do_find()
{
    Doreplace = 0;
    Srch_sign = 1;
    switch(av[0][0]) {
    case 'f':
	strcpy(Fstr, av[1]);
	break;
    case 'p':
	Srch_sign = -1;
	break;
    }
    search_operation();
}


void
search_operation()
{
    int flen = strlen(Fstr);
    int rlen = strlen(Rstr);
    char senabled = 0;
    register u_char *ptr;
    register int i, col;

    TU;
    text_sync();
    if (!flen) {
	title("No find pattern");
	Abortcommand = 1;
	return;
    }

    col = E.Column;
    if (col >= strlen(E.List[E.Line]))
	col = strlen(E.List[E.Line]);
    for (i = E.Line;;) {
	ptr = E.List[i];
	if (Srch_sign > 0) {
	    while (ptr[col]) {
		if (Fstr[0] == ptr[col] &&
		strncmp(Fstr,ptr+col,flen) == 0 &&
		senabled) {
		    goto found;
		}
		senabled = 1;
		++col;
	    }
	    senabled = 1;
	    if (++i >= E.Lines)
		break;
	    col = 0;
	} else {
	    while (col >= 0) {
		if (Fstr[0] == ptr[col] &&
		strncmp(Fstr,ptr+col,flen) == 0 &&
		senabled) {
		    goto found;
		}
		senabled = 1;
		--col;
	    }
	    senabled = 1;
	    if (--i < 0)
		break;
	    col = strlen(E.List[i]);
	}
    }
    MShowTitle = 1;
    title("Pattern Not Found");
    Abortcommand = 1;
    return;

found:
    E.Line = i;
    E.Column = col;

    text_load();
    if (Doreplace) {
	if (rlen > flen && rlen-flen+strlen(ptr) > 254) {
	    title("Replace: Line Too Long");
	    Abortcommand = 1;
	    return;
	}
	if (Clen-col-flen >= 0) {
	    bmov(Current+col+flen, Current+col+rlen, Clen-col-flen+1);
	    bmov(Rstr, Current+col, rlen);
	    Clen += rlen-flen;
	}
	text_sync();
	text_redisplaycurrline();
    } else {
	text_sync();
    }
}


SHAR_En"b