v02i051: Unify TEXT fields from ACCELL Part 2/5

Mark Hargrove ustel at well.UUCP
Thu Feb 11 10:46:35 AEST 1988


Comp.sources.misc: Volume 2, Issue 51
Submitted-By: "Mark Hargrove" <ustel at well.UUCP>
Archive-Name: accell-text/Part2

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./fileio.c`
then
echo "writing ./fileio.c"
cat > ./fileio.c << '\Rogue\Monster\'
/*
 * Name:	MicroEMACS
 * 		System V file I/O
 */
#include	"def.h"

# ifndef F_OK
# define F_OK	0
# define X_OK	1
# define W_OK	2
# define R_OK	4
# endif

/*
 * Move bytes, overlaps OK (daveb).
 *
 * Doesn't really belong here, but it's system specific since it
 * is in assembler in some C libraries.
 */
bcopy( from, to, cnt )
char *from;
char *to;
int cnt;
{
	if ( from == to )
		return;

	if( from > to )
	{
		while( cnt-- )
			*to++ = *from++;
	}
	else
	{
		to += cnt;
		from += cnt;
		while( cnt-- )
			*--to = *--from;
	}
}


static	FILE	*ffp;

/*
 * Open a file for reading.
 */
ffropen(fn)
char	*fn;
{
	if ((ffp=fopen(fn, "r")) == NULL)
		return (FIOFNF);
	return (FIOSUC);
}

/*
 * Open a file for writing.
 * Return TRUE if all is well, and
 * FALSE on error (cannot create).
 */
ffwopen(fn)
char	*fn;
{
	if ((ffp=fopen(fn, "w")) == NULL) {
		ewprintf("Cannot open file for writing");
		return (FIOERR);
	}
	return (FIOSUC);
}

/*
 * Close a file.
 * Should look at the status.
 */
ffclose()
{
	(VOID) fclose(ffp);
	return (FIOSUC);
}

/*
 * Write a line to the already
 * opened file. The "buf" points to the
 * buffer, and the "nbuf" is its length, less
 * the free newline. Return the status.
 * Check only at the newline.
 */
ffputline(buf, nbuf)
register char	buf[];
{
	register int	i;

	for (i=0; i<nbuf; ++i)
		putc(buf[i]&0xFF, ffp);
	putc('\n', ffp);
	if (ferror(ffp) != FALSE) {
		ewprintf("Write I/O error");
		return (FIOERR);
	}
	return (FIOSUC);
}

/*
 * Read a line from a file, and store the bytes
 * in the supplied buffer. Stop on end of file or end of
 * line. Don't get upset by files that don't have an end of
 * line on the last line; this seem to be common on CP/M-86 and
 * MS-DOS (the suspected culprit is VAX/VMS kermit, but this
 * has not been confirmed. If this is sufficiently researched
 * it may be possible to pull this kludge). Delete any CR
 * followed by an LF. This is mainly for runoff documents,
 * both on VMS and on Ultrix (they get copied over from
 * VMS systems with DECnet).
 */
ffgetline(buf, nbuf)
register char	buf[];
{
	register int	c;
	register int	i;

	i = 0;
	for (;;) {
		c = getc(ffp);
		if (c == '\r') {		/* Delete any non-stray	*/
			c = getc(ffp);		/* carriage returns.	*/
			if (c != '\n') {
				if (i >= nbuf-1) {
					ewprintf("File has long line");
					return (FIOERR);
				}
				buf[i++] = '\r';
			}
		}
		if (c==EOF || c=='\n')		/* End of line.		*/
			break;
		if (i >= nbuf-1) {
			ewprintf("File has long line");
			return (FIOERR);
		}
		buf[i++] = c;
	}
	if (c == EOF) {				/* End of file.		*/
		if (ferror(ffp) != FALSE) {
			ewprintf("File read error");
			return (FIOERR);
		}
		if (i == 0)			/* Don't get upset if	*/
			return (FIOEOF);	/* no newline at EOF.	*/
	}
	buf[i] = 0;
	return (FIOSUC);
}

#if	BACKUP
/*
 * Rename the file "fname" into a backup
 * copy. On Unix the backup has the same name as the
 * original file, with a "~" on the end; this seems to
 * be newest of the new-speak. The error handling is
 * all in "file.c". The "unlink" is perhaps not the
 * right thing here; I don't care that much as
 * I don't enable backups myself.
 */
fbackupfile(fname)
char	*fname;
{
	register char	*nname;

	if ((nname=malloc(strlen(fname)+1+1)) == NULL)
		return (ABORT);
	(void) strcpy(nname, fname);
	(void) strcat(nname, "~");
	(void) unlink(nname);			/* Ignore errors.	*/

	/* no rename on System V, so do it dangerous way. */
	if ( link(fname, nname) < 0 || unlink(fname) < 0 ) {
		free(nname);
		return (FALSE);
	}
	free(nname);
	return (TRUE);
}
#endif

/*
 * The string "fn" is a file name.
 * Perform any required case adjustments. All sustems
 * we deal with so far have case insensitive file systems.
 * We zap everything to lower case. The problem we are trying
 * to solve is getting 2 buffers holding the same file if
 * you visit one of them with the "caps lock" key down.
 * On UNIX file names are dual case, so we leave
 * everything alone.
 */
/*ARGSUSED*/
adjustcase(fn)
register char	*fn;
{
#if	0
	register int	c;

	while ((c = *fn) != 0) {
		if (c>='A' && c<='Z')
			*fn = c + 'a' - 'A';
		++fn;
	}
#endif
}



#ifdef	STARTUP
#include <sys/types.h>
#include <sys/file.h>
/*
 * find the users startup file, and return it's name. Check for
 * $HOME/.mg then for $HOME/.emacs, then give up.
 */
char *
startupfile() 
{
	register char	*file;
	static char	home[NFILEN];
	char		*getenv();

	if ( (file = getenv("HOME")) == NULL 
	     || strlen(file)+7 >= NFILEN - 1 ) 
		return NULL;
	(VOID) strcpy(home, file);
	file = &(home[strlen(home)]);
	*file++ = '/';

	(VOID) strcpy(file, ".mg");
	if (access(home, F_OK ) == 0) return home;

	(VOID) strcpy(file, ".emacs");
	if (access(home, F_OK) == 0) return home;

	return NULL;
}
#endif
\Rogue\Monster\
else
  echo "will not over write ./fileio.c"
fi
if `test ! -s ./kbd.c`
then
echo "writing ./kbd.c"
cat > ./kbd.c << '\Rogue\Monster\'
/*
 *		Terminal independent keyboard handling.
 */
#include	"def.h"

static mapin();

#ifdef	DPROMPT
#define	PROMPTL	80
  char	prompt[PROMPTL], *promptp;
#endif

/*
 * All input from the user (should!) go through
 * getkey. Quotep is true to get raw keys, false to
 * get 11-bit code keys.
 * Getkey is responsible for putting keystrokes away
 * for macros. It also takes keystrokes out of the macro,
 * though other input routines will can also do this.
 * Read in a key, doing the terminal
 * independent prefix handling. The terminal specific
 * "getkbd" routine gets the first swing, and may return
 * one of the special codes used by the special keys
 * on the keyboard. The "getkbd" routine returns the
 * C0 controls as received; this routine moves them to
 * the right spot in 11 bit code.
 * If the KPROMPT bit in the flags is set and DPROMPT is
 * defined, do delayed prompting.  (dprompt routine is 
 * in sys/???/ttyio.c)
 */
KEY
getkey(f)
   register int f;
{
	register KEY	c;
	KEY		keychar();
	int		getkbd(), ttgetc();

	if (kbdmop != NULL)
		return *kbdmop++;
#ifdef	DPROMPT
	if(!(f&KPROMPT))
		prompt[0] = '\0';
#endif
	c = (KEY) mapin(getkbd);
#ifdef	DPROMPT
	if(f&KPROMPT)
	{
		if(promptp > prompt)
			*(promptp-1) = ' ';
		if(promptp >= &prompt[PROMPTL-8])
			f &= ~KPROMPT;
				/* must have a lot of prefixes.... */
	}
#endif
	if ((f&KQUOTE) == 0)
	{
#ifdef	DO_METAKEY
		if ((c & ~KCHAR) == KCTRL)	/* Function key		*/
			c = ((char) c) & KCHAR;/* remove wrapping	*/
		else if ((c >= 0x80) && (c <= 0xFF))
		{		/* real meta key	*/
			c = ((char) c) & 0x7f;	/* Get the key and mode map it */
			if ((mode&MFLOW) != 0)
				if (c == CCHR('^')) c = CCHR('Q');
				else if (c == CCHR('\\')) c = CCHR('S');
			if ((mode&MBSMAP) != 0)
				if (c == CCHR('H')) c = 0x7f;
				else if (c == 0x7f) c = CCHR('H');
			c = KMETA | keychar(c & ~0x80, TRUE);
		}
#endif
#ifdef	DPROMPT
		if(f&KPROMPT)
		{
			keyname(promptp, (c<=0x1F && c>=0x00)?KCTRL|(c+'@'):c);
			strcat(promptp, "-");
		}
#endif
		if (c == METACH)		/* M-			*/
			c = KMETA | keychar(mapin(ttgetc), TRUE);
		else if (c == CTRLCH)		/* C-			*/
			c = KCTRL | keychar(mapin(ttgetc), TRUE);
		else if (c == CTMECH)		/* C-M-			*/
			c = KCTRL | KMETA | keychar(mapin(ttgetc), TRUE);
		else if (c<=0x1F && c>=0x00)	/* Relocate control.	*/
			c = KCTRL | (c+'@');
		if (c == (KCTRL|'X'))		/* C-X			*/
			c = KCTLX | keychar(mapin(ttgetc), TRUE);
	}

	if ((f&KNOMAC) == 0 && kbdmip != NULL)
	{
		if (kbdmip+1 > &kbdm[NKBDM-3])
		{	/* macro overflow */
			(VOID) ctrlg(FALSE, 0, KRANDOM);
			ewprintf("Keyboard macro overflow");
			ttflush();
			return (KCTRL|'G');		/* ^G it for us	*/
		}
		*kbdmip++ = c;
	}
#ifdef	DPROMPT
	if(f&KPROMPT)
	{
		keyname(promptp, c);
		promptp += strlen(promptp);
		*promptp++ = '-';
		*promptp = '\0';
	}
#endif
	return (c);
}

/*
 * go get a key, and run it through whatever mapping the modes
 * specify.
 */
static mapin(get) int (*get)();
{
	register int	c;

#ifdef	DPROMPT
	if(prompt[0]!='\0' && ttwait())
	{
		ewprintf("%s", prompt);		/* avoid problems with % */
		update();			/* put the cursor back	 */
		epresf = KPROMPT;
	}
#endif
	c = (*get)();
	if ((mode&MFLOW) != 0)
	{
		while (c == CCHR('S') || c == CCHR('Q'))
			c = (*get)();
		if (c == CCHR('^')) c = CCHR('Q');
		else if (c == CCHR('\\')) c = CCHR('S');
	}
	if ((mode&MBSMAP) != 0)
		if (c == CCHR('H')) c = 0x7f;
		else if (c == 0x7f) c = CCHR('H');
	return c;
}
/*
 * Transform a key code into a name,
 * using a table for the special keys and combination
 * of some hard code and some general processing for
 * the rest. None of this code is terminal specific any
 * more. This makes adding keys easier.
 */
VOID
keyname(cp, k) register char *cp; register int k;
{
	register char	*np;
	register int	c;
	char		nbuf[3];

	static	char	hex[] = {
		'0',	'1',	'2',	'3',
		'4',	'5',	'6',	'7',
		'8',	'9',	'A',	'B',
		'C',	'D',	'E',	'F'
	};

	if ((k&KCTLX) != 0) {			/* C-X prefix.		*/
		*cp++ = 'C';
		*cp++ = '-';
		*cp++ = 'x';
		*cp++ = ' ';
	}
	if ((k&KMETA) != 0) {			/* Add M- mark.		*/
		*cp++ = 'E';
		*cp++ = 'S';
		*cp++ = 'C';
		*cp++ = ' ';
	}
	if ((k&KCHAR)>=KFIRST && (k&KCHAR)<=KLAST)
	{
		if ((np=keystrings[(k&KCHAR)-KFIRST]) != NULL)
		{
			if ((k&KCTRL) != 0)
			{
				*cp++ = 'C';
				*cp++ = '-';
			}
			(VOID) strcpy(cp, np);
			return;
		}
	}
	c = k & ~(KMETA|KCTLX);
	if (c == (KCTRL|'I'))	/* Some specials.	*/
		np = "TAB";
	else if (c == (KCTRL|'M'))
		np = "RET";
	else if (c == (KCTRL|'J'))
		np = "LFD";
	else if (c == ' ')
		np = "SPC";
	else if (c == 0x7F)
		np = "DEL";
	else if (c == (KCTRL|'['))
		np = "ESC";
	else
	{
		if ((k&KCTRL) != 0)
		{		/* Add C- mark.		*/
			*cp++ = 'C';
			*cp++ = '-';
		}
		if ((k&(KCTRL|KMETA|KCTLX)) != 0 && ISUPPER(k&KCHAR) != FALSE)
			k = TOLOWER(k&KCHAR);
		np = &nbuf[0];
		if (((k&KCHAR)>=0x20 && (k&KCHAR)<=0x7E)
				||  ((k&KCHAR)>=0xA0 && (k&KCHAR)<=0xFE))
		{
			nbuf[0] = k&KCHAR;	/* Graphic.		*/
			nbuf[1] = 0;
		}
		else
		{			/* Non graphic.		*/
			nbuf[0] = hex[(k>>4)&0x0F];
			nbuf[1] = hex[k&0x0F];
			nbuf[2] = 0;
		}
	}
	(VOID) strcpy(cp, np);
}

/*
 * turn a key into an internal char.
 */
KEY
keychar(c, f) register int c, f;
{

	if (f == TRUE && ISLOWER(c) != FALSE)
		c = TOUPPER(c);
	else if (c>=0x00 && c<=0x1F)		/* Relocate control.	*/
		c = (KCTRL|(c+'@'));
	return (KEY) c;
}
\Rogue\Monster\
else
  echo "will not over write ./kbd.c"
fi
if `test ! -s ./line.c`
then
echo "writing ./line.c"
cat > ./line.c << '\Rogue\Monster\'
/*
 *		Text line handling.
 * The functions in this file
 * are a general set of line management
 * utilities. They are the only routines that
 * touch the text. They also touch the buffer
 * and window structures, to make sure that the
 * necessary updating gets done. There are routines
 * in this file that handle the kill buffer too.
 * It isn't here for any good reason.
 *
 * Note that this code only updates the dot and
 * mark values in the window list. Since all the code
 * acts on the current window, the buffer that we
 * are editing must be being displayed, which means
 * that "b_nwnd" is non zero, which means that the
 * dot and mark values in the buffer headers are
 * nonsense.
 */
#include	"def.h"

#define	NBLOCK	16			/* Line block chunk size	*/

#ifndef	KBLOCK
#define	KBLOCK	256			/* Kill buffer block size.	*/
#endif

static char	*kbufp	= NULL;		/* Kill buffer data.		*/
static RSIZE	kused	= 0;		/* # of bytes used in KB.	*/
static RSIZE	ksize	= 0;		/* # of bytes allocated in KB.	*/
static RSIZE	kstart  = 0;		/* # of first used byte in KB.	*/
char	*malloc();
/*
 * This routine allocates a block
 * of memory large enough to hold a LINE
 * containing "used" characters. The block is
 * always rounded up a bit. Return a pointer
 * to the new block, or NULL if there isn't
 * any memory left. Print a message in the
 * message line if no space.
 */
LINE	*
lalloc(used) register RSIZE used;
{
	register LINE	*lp;
	register int	size;

	/*NOSTRICT*/
	size = (NBLOCK-1+used) & ~(NBLOCK-1);
	if (size == 0)				/* Assume that an empty	*/
		size = NBLOCK;			/* line is for type-in.	*/
	/*NOSTRICT*/
	if ((lp=(LINE *)malloc(sizeof(LINE)+size)) == NULL)
	{
		ewprintf("Can't get %d bytes", sizeof(LINE) + size);
		return (NULL);
	}
	lp->l_size = size;
	/*NOSTRICT*/
	lp->l_used = used;
	return (lp);
}

/*
 * Delete line "lp". Fix all of the
 * links that might point at it (they are
 * moved to offset 0 of the next line.
 * Unlink the line from whatever buffer it
 * might be in. Release the memory. The
 * buffers are updated too; the magic conditions
 * described in the above comments don't hold
 * here.
 */
VOID
lfree(lp) register LINE *lp;
{
	register BUFFER	*bp;
	register WINDOW	*wp;

	wp = wheadp;
	while (wp != NULL)
	{
		if (wp->w_linep == lp)
			wp->w_linep = lp->l_fp;
		if (wp->w_dotp  == lp)
		{
			wp->w_dotp  = lp->l_fp;
			wp->w_doto  = 0;
		}
		if (wp->w_markp == lp)
		{
			wp->w_markp = lp->l_fp;
			wp->w_marko = 0;
		}
		wp = wp->w_wndp;
	}
	bp = bheadp;
	while (bp != NULL)
	{
		if (bp->b_nwnd == 0)
		{
			if (bp->b_dotp  == lp)
			{
				bp->b_dotp = lp->l_fp;
				bp->b_doto = 0;
			}
			if (bp->b_markp == lp)
			{
				bp->b_markp = lp->l_fp;
				bp->b_marko = 0;
			}
		}
		bp = bp->b_bufp;
	}
	lp->l_bp->l_fp = lp->l_fp;
	lp->l_fp->l_bp = lp->l_bp;
	free((char *) lp);
}

/*
 * This routine gets called when
 * a character is changed in place in the
 * current buffer. It updates all of the required
 * flags in the buffer and window system. The flag
 * used is passed as an argument; if the buffer is being
 * displayed in more than 1 window we change EDIT to
 * HARD. Set MODE if the mode line needs to be
 * updated (the "*" has to be set).
 * Modified by Walter Bright to reduce update times.
 */
VOID
lchange(flag) register int flag;
{
	register WINDOW	*wp;

	if ((curbp->b_flag&BFCHG) == 0)
	{	/* First change, so 	*/
		flag |= WFMODE;			/* update mode lines.	*/
		curbp->b_flag |= BFCHG;
	}
	wp = wheadp;
	while (wp != NULL)
	{
		if (wp->w_bufp == curbp)
		{
			wp->w_flag |= flag;
			if (wp != curwp) wp->w_flag |= WFHARD;
			}
		wp = wp->w_wndp;
	}
}

/*
 * Insert "n" copies of the character "c"
 * at the current location of dot. In the easy case
 * all that happens is the text is stored in the line.
 * In the hard case, the line has to be reallocated.
 * When the window list is updated, take special
 * care; I screwed it up once. You always update dot
 * in the current window. You update mark, and a
 * dot in another window, if it is greater than
 * the place where you did the insert. Return TRUE
 * if all is well, and FALSE on errors.
 *
 * Added 11-1-87 by s.k.henry: overstrike mode for text insertion.
 * Not too hard, mostly just modifies the meaning of 'n'.
 */
linsert(n, c) RSIZE n;
{
	register char	*cp1;
	register char	*cp2;
	register LINE	*lp1;
	LINE		*lp2;
	LINE		*lp3;
	register int	doto;
	register RSIZE	i;
	WINDOW		*wp;
#ifndef max
#define max(a,b) ((a) > (b)) ? (a) : (b)
#endif

	lchange(WFEDIT);
	lp1 = curwp->w_dotp;			/* Current line		*/
	if (lp1 == curbp->b_linep)		/* At the end: special	*/
	{
		if (curwp->w_doto != 0)
		{
			ewprintf("bug: linsert");
			return (FALSE);
		}
		if ((lp2=lalloc(n)) == NULL)	/* Allocate new line	*/
			return (FALSE);
		lp3 = lp1->l_bp;		/* Previous line	*/
		lp3->l_fp = lp2;		/* Link in		*/
		lp2->l_fp = lp1;
		lp1->l_bp = lp2;
		lp2->l_bp = lp3;
		for (i=0; i<n; ++i)
			lp2->l_text[i] = c;
		wp = wheadp;			/* Update windows	*/
		while (wp != NULL)
		{
			if (wp->w_linep == lp1)
				wp->w_linep = lp2;
			if (wp->w_dotp == lp1)
				wp->w_dotp = lp2;
			if (wp->w_markp == lp1)
				wp->w_markp = lp2;
			wp = wp->w_wndp;
		}
		/*NOSTRICT*/
		curwp->w_doto = n;
		return (TRUE);
	}
	doto = curwp->w_doto;			/* Save for later.	*/

#define INS_MODE ((mode & MOVRSTK) == 0)
#define OVR_MODE ((mode & MOVRSTK) == MOVRSTK)

	/*NOSTRICT*/
	if ((OVR_MODE && (doto+n > lp1->l_size))
		|| (INS_MODE && (lp1->l_used+n > lp1->l_size)))
	{					/* Hard: reallocate	*/
		if ((lp2=lalloc((RSIZE) (lp1->l_used+n))) == NULL)
			return (FALSE);
		cp1 = &lp1->l_text[0];
		cp2 = &lp2->l_text[0];
		while (cp1 != &lp1->l_text[doto])
			*cp2++ = *cp1++;
		if (INS_MODE)
		{
			/*NOSTRICT*/
			cp2 += n;
			while (cp1 != &lp1->l_text[lp1->l_used])
				*cp2++ = *cp1++;
		}
		lp1->l_bp->l_fp = lp2;
		lp2->l_fp = lp1->l_fp;
		lp1->l_fp->l_bp = lp2;
		lp2->l_bp = lp1->l_bp;
		free((char *) lp1);
	}
	else
	{					/* Easy: in place	*/
		lp2 = lp1;			/* Pretend new line	*/
		if (INS_MODE)
		{
			/*NOSTRICT*/
			lp2->l_used += n;
			cp2 = &lp1->l_text[lp1->l_used];

			cp1 = cp2-n;
			while (cp1 != &lp1->l_text[doto])
				*--cp2 = *--cp1;
		}
		else
		{
			/*NOSTRICT*/
			lp2->l_used = max( (doto+n), (lp2->l_used));
		}
	}
	for (i=0; i<n; ++i)			/* Add the characters	*/
		lp2->l_text[doto+i] = c;
	wp = wheadp;				/* Update windows	*/
	while (wp != NULL)
	{
		if (wp->w_linep == lp1)
			wp->w_linep = lp2;
		if (wp->w_dotp == lp1)
		{
			wp->w_dotp = lp2;
			if (wp==curwp || wp->w_doto>doto)
				/*NOSTRICT*/
				wp->w_doto += n;
		}
		if (wp->w_markp == lp1)
		{
			wp->w_markp = lp2;
			if (wp->w_marko > doto)
				/*NOSTRICT*/
				wp->w_marko += n;
		}
		wp = wp->w_wndp;
	}
	return (TRUE);
}

/*
 * Insert a newline into the buffer
 * at the current location of dot in the current
 * window. The funny ass-backwards way it does things
 * is not a botch; it just makes the last line in
 * the file not a special case. Return TRUE if everything
 * works out and FALSE on error (memory allocation
 * failure). The update of dot and mark is a bit
 * easier then in the above case, because the split
 * forces more updating.
 */
lnewline()
{
	register char	*cp1;
	register char	*cp2;
	register LINE	*lp1;
	LINE		*lp2;
	register int	doto;
	WINDOW		*wp;

	lchange(WFHARD);
	lp1  = curwp->w_dotp;			/* Get the address and	*/
	doto = curwp->w_doto;			/* offset of "."	*/
	if ((lp2=lalloc((RSIZE) doto)) == NULL)	/* New first half line	*/
		return (FALSE);
	cp1 = &lp1->l_text[0];			/* Shuffle text around	*/
	cp2 = &lp2->l_text[0];
	while (cp1 != &lp1->l_text[doto])
		*cp2++ = *cp1++;
	cp2 = &lp1->l_text[0];
	while (cp1 != &lp1->l_text[lp1->l_used])
		*cp2++ = *cp1++;
	lp1->l_used -= doto;
	lp2->l_bp = lp1->l_bp;
	lp1->l_bp = lp2;
	lp2->l_bp->l_fp = lp2;
	lp2->l_fp = lp1;
	wp = wheadp;				/* Windows		*/
	while (wp != NULL)
	{
		if (wp->w_linep == lp1)
			wp->w_linep = lp2;
		if (wp->w_dotp == lp1)
		{
			if (wp->w_doto < doto)
				wp->w_dotp = lp2;
			else
				wp->w_doto -= doto;
		}
		if (wp->w_markp == lp1)
		{
			if (wp->w_marko < doto)
				wp->w_markp = lp2;
			else
				wp->w_marko -= doto;
		}
		wp = wp->w_wndp;
	}	
	return (TRUE);
}

/*
 * This function deletes "n" bytes,
 * starting at dot. It understands how do deal
 * with end of lines, etc. It returns TRUE if all
 * of the characters were deleted, and FALSE if
 * they were not (because dot ran into the end of
 * the buffer. The "kflag" indicates either no insertion,
 * or direction of insertion into the kill buffer.
 */
ldelete(n, kflag) RSIZE n;
{
	register char	*cp1;
	register char	*cp2;
	register LINE	*dotp;
	register int	doto;
	register RSIZE	chunk;
	WINDOW		*wp;

	/*
	 * HACK - doesn't matter, and fixes back-over-nl bug for empty
	 *	kill buffers.
	 */
	if (kused == kstart) kflag = KFORW;

	while (n != 0)
	{
		dotp = curwp->w_dotp;
		doto = curwp->w_doto;
		if (dotp == curbp->b_linep)	/* Hit end of buffer.	*/
			return (FALSE);
		chunk = dotp->l_used-doto;	/* Size of chunk.	*/
		if (chunk > n)
			chunk = n;
		if (chunk == 0)
		{		/* End of line, merge.	*/
			lchange(WFHARD);
			if (ldelnewline() == FALSE
			|| (kflag!=KNONE && kinsert('\n', kflag)==FALSE))
				return (FALSE);
			--n;
			continue;
		}
		lchange(WFEDIT);
		cp1 = &dotp->l_text[doto];	/* Scrunch text.	*/
		cp2 = cp1 + chunk;
		if (kflag == KFORW)
		{
			while (ksize - kused < chunk)
				if (kgrow(FALSE) == FALSE) return FALSE;
			bcopy(cp1, &(kbufp[kused]), (int) chunk);
			kused += chunk;
		}
		else if (kflag == KBACK)
		{
			while (kstart < chunk)
				if (kgrow(TRUE) == FALSE) return FALSE;
			bcopy(cp1, &(kbufp[kstart-chunk]), (int) chunk);
			kstart -= chunk;
		} else if (kflag != KNONE) panic("broken ldelete call");
		while (cp2 != &dotp->l_text[dotp->l_used])
			*cp1++ = *cp2++;
		dotp->l_used -= (int) chunk;
		wp = wheadp;			/* Fix windows		*/
		while (wp != NULL)
		{
			if (wp->w_dotp==dotp && wp->w_doto>=doto)
			{
				/*NOSTRICT*/
				wp->w_doto -= chunk;
				if (wp->w_doto < doto)
					wp->w_doto = doto;
			}	
			if (wp->w_markp==dotp && wp->w_marko>=doto)
			{
				/*NOSTRICT*/
				wp->w_marko -= chunk;
				if (wp->w_marko < doto)
					wp->w_marko = doto;
			}
			wp = wp->w_wndp;
		}
		n -= chunk;
	}
	return (TRUE);
}

/*
 * Delete a newline. Join the current line
 * with the next line. If the next line is the magic
 * header line always return TRUE; merging the last line
 * with the header line can be thought of as always being a
 * successful operation, even if nothing is done, and this makes
 * the kill buffer work "right". Easy cases can be done by
 * shuffling data around. Hard cases require that lines be moved
 * about in memory. Return FALSE on error and TRUE if all
 * looks ok.
 */
ldelnewline()
{
	register char	*cp1;
	register char	*cp2;
	register LINE	*lp1;
	LINE		*lp2;
	LINE		*lp3;
	WINDOW		*wp;

	lp1 = curwp->w_dotp;
	lp2 = lp1->l_fp;
	if (lp2 == curbp->b_linep)
	{		/* At the buffer end.	*/
		if (lp1->l_used == 0)		/* Blank line.		*/
			lfree(lp1);
		return (TRUE);
	}
	if (lp2->l_used <= lp1->l_size-lp1->l_used)
	{
		cp1 = &lp1->l_text[lp1->l_used];
		cp2 = &lp2->l_text[0];
		while (cp2 != &lp2->l_text[lp2->l_used])
			*cp1++ = *cp2++;
		wp = wheadp;
		while (wp != NULL)
		{
			if (wp->w_linep == lp2)
				wp->w_linep = lp1;
			if (wp->w_dotp == lp2)
			{
				wp->w_dotp  = lp1;
				wp->w_doto += lp1->l_used;
			}
			if (wp->w_markp == lp2)
			{
				wp->w_markp  = lp1;
				wp->w_marko += lp1->l_used;
			}
			wp = wp->w_wndp;
		}		
		lp1->l_used += lp2->l_used;
		lp1->l_fp = lp2->l_fp;
		lp2->l_fp->l_bp = lp1;
		free((char *) lp2);
		return (TRUE);
	}
	if ((lp3=lalloc((RSIZE) (lp1->l_used+lp2->l_used))) == NULL)
		return (FALSE);
	cp1 = &lp1->l_text[0];
	cp2 = &lp3->l_text[0];
	while (cp1 != &lp1->l_text[lp1->l_used])
		*cp2++ = *cp1++;
	cp1 = &lp2->l_text[0];
	while (cp1 != &lp2->l_text[lp2->l_used])
		*cp2++ = *cp1++;
	lp1->l_bp->l_fp = lp3;
	lp3->l_fp = lp2->l_fp;
	lp2->l_fp->l_bp = lp3;
	lp3->l_bp = lp1->l_bp;
	wp = wheadp;
	while (wp != NULL)
	{
		if (wp->w_linep==lp1 || wp->w_linep==lp2)
			wp->w_linep = lp3;
		if (wp->w_dotp == lp1)
			wp->w_dotp  = lp3;
		else if (wp->w_dotp == lp2)
		{
			wp->w_dotp  = lp3;
			wp->w_doto += lp1->l_used;
		}
		if (wp->w_markp == lp1)
			wp->w_markp  = lp3;
		else if (wp->w_markp == lp2)
		{
			wp->w_markp  = lp3;
			wp->w_marko += lp1->l_used;
		}
		wp = wp->w_wndp;
	}
	free((char *) lp1);
	free((char *) lp2);
	return (TRUE);
}

/*
 * Replace plen characters before dot with argument string.
 * Control-J characters in st are interpreted as newlines.
 * There is a casehack disable flag (normally it likes to match
 * case of replacement to what was there).
 */
lreplace(plen, st, f)
register RSIZE	plen;			/* length to remove		*/
char		*st;			/* replacement string		*/
int		f;			/* case hack disable		*/
{
	register RSIZE	rlen;		/* replacement length		*/
	register int	rtype;		/* capitalization 		*/
	register int	c;		/* used for random characters	*/
	register int	doto;		/* offset into line		*/

	/*
	 * Find the capitalization of the word that was found.
	 * f says use exact case of replacement string (same thing that
	 * happens with lowercase found), so bypass check.
	 */
	/*NOSTRICT*/
	(VOID) backchar(TRUE, (int) plen, KRANDOM);
	rtype = _L;
	c = lgetc(curwp->w_dotp, curwp->w_doto);
	if (ISUPPER(c)!=FALSE  &&  f==FALSE)
	{
		rtype = _U|_L;
		if (curwp->w_doto+1 < llength(curwp->w_dotp))
		{
			c = lgetc(curwp->w_dotp, curwp->w_doto+1);
			if (ISUPPER(c) != FALSE)
			{
				rtype = _U;
			}
		}
	}

	/*
	 * make the string lengths match (either pad the line
	 * so that it will fit, or scrunch out the excess).
	 * be careful with dot's offset.
	 */
	rlen = strlen(st);
	doto = curwp->w_doto;
	if (plen > rlen)
		(VOID) ldelete((RSIZE) (plen-rlen), KNONE);
	else if (plen < rlen)
	{
		if (linsert((RSIZE) (rlen-plen), ' ') == FALSE)
			return (FALSE);
	}
	curwp->w_doto = doto;

	/*
	 * do the replacement:  If was capital, then place first 
	 * char as if upper, and subsequent chars as if lower.  
	 * If inserting upper, check replacement for case.
	 */
	while ((c = *st++&0xff) != '\0')
	{
		if ((rtype&_U)!=0  &&  ISLOWER(c)!=0)
			c = TOUPPER(c);
		if (rtype == (_U|_L))
			rtype = _L;
		if (c == SEOL)
		{
			if (curwp->w_doto == llength(curwp->w_dotp))
				(VOID) forwchar(FALSE, 1, KRANDOM);
			else
			{
				if (ldelete((RSIZE) 1, KNONE) != FALSE)
					(VOID) lnewline();
			}
		}
		else if (curwp->w_dotp == curbp->b_linep)
		{
			(VOID) linsert((RSIZE) 1, c);
		}
		else if (curwp->w_doto == llength(curwp->w_dotp))
		{
			if (ldelete((RSIZE) 1, KNONE) != FALSE)
				(VOID) linsert((RSIZE) 1, c);
		} else
			lputc(curwp->w_dotp, curwp->w_doto++, c);
	}
	lchange(WFHARD);
	return (TRUE);
}

/*
 * Delete all of the text
 * saved in the kill buffer. Called by commands
 * when a new kill context is being created. The kill
 * buffer array is released, just in case the buffer has
 * grown to immense size. No errors.
 */
VOID
kdelete()
{
	if (kbufp != NULL)
	{
		free((char *) kbufp);
		kbufp = NULL;
		kstart = kused = ksize = 0;
	}
}

/*
 * Insert a character to the kill buffer,
 * enlarging the buffer if there isn't any room. Always
 * grow the buffer in chunks, on the assumption that if you
 * put something in the kill buffer you are going to put
 * more stuff there too later. Return TRUE if all is
 * well, and FALSE on errors. Print a message on
 * errors. Dir says whether to put it at back or front.
 */
kinsert(c, dir)
{

	if (kused == ksize && dir == KFORW && kgrow(FALSE) == FALSE)
		return FALSE;
	if (kstart == 0 && dir == KBACK && kgrow(TRUE) == FALSE)
		return FALSE;
	if (dir == KFORW) kbufp[kused++] = c;
	else if (dir == KBACK) kbufp[--kstart] = c;
	else panic("broken kinsert call");		/* Oh shit! */
	return (TRUE);
}

/*
 * kgrow - just get more kill buffer for the callee. back is true if
 * we are trying to get space at the beginning of the kill buffer.
 */
kgrow(back)
{
	register int	nstart;
	register char	*nbufp;

	if ((nbufp=malloc((int)(ksize+KBLOCK))) == NULL)
	{
		ewprintf("Can't get %ld bytes", (long)(ksize+KBLOCK));
		return (FALSE);
	}
	nstart = (back == TRUE) ? (kstart + KBLOCK) : (KBLOCK / 4) ;
	bcopy(&(kbufp[kstart]), &(nbufp[nstart]), (int) (kused-kstart));
	if (kbufp != NULL)
		free((char *) kbufp);
	kbufp  = nbufp;
	ksize += KBLOCK;
	kused = kused - kstart + nstart;
	kstart = nstart;
	return TRUE;
}

/*
 * This function gets characters from
 * the kill buffer. If the character index "n" is
 * off the end, it returns "-1". This lets the caller
 * just scan along until it gets a "-1" back.
 */
kremove(n)
{
	if (n < 0 || n + kstart >= kused)
		return (-1);
	return (kbufp[n + kstart] & 0xFF);
}
\Rogue\Monster\
else
  echo "will not over write ./line.c"
fi
if `test ! -s ./main.c`
then
echo "writing ./main.c"
cat > ./main.c << '\Rogue\Monster\'
/*
 *		Mainline, macro commands.
 */
#include	"def.h"

int	thisflag;			/* Flags, this command		*/
int	lastflag;			/* Flags, last command		*/
int	curgoal;			/* Goal column			*/
BUFFER	*curbp;				/* Current buffer		*/
WINDOW	*curwp;				/* Current window		*/
BUFFER	*bheadp;			/* BUFFER listhead		*/
WINDOW	*wheadp = (WINDOW *)NULL;	/* WINDOW listhead		*/
KEY	kbdm[NKBDM] = {(KCTLX|')')};	/* Macro			*/
KEY	*kbdmip;			/* Input  for above		*/
KEY	*kbdmop;			/* Output for above		*/
char	pat[NPAT];			/* Pattern			*/
#ifdef	HASH
SYMBOL	*symbol[NSHASH];		/* Symbol table listhead.	*/
#else
/* should really be a *symbol, but don't want to break the hash code yet */
SYMBOL  *symbol[1] = {(SYMBOL *)NULL};
#endif
SYMBOL	*binding[NKEYS];		/* Key bindings.		*/
#ifdef	DPROMPT
extern char prompt[], *promptp;		/* delayed prompting		*/
#endif
VOID	edinit();

VOID
main(argc, argv)
   int  argc;
   char *argv[];
{
	register KEY	c;
	register int	f;
	register int	n;
	register int	mflag;
#ifdef	STARTUP
	char		*sfile, *startupfile();
#endif
	char		bname[NBUFN];

#ifdef SYSINIT
	SYSINIT;				/* system dependent.	*/
#endif
	vtinit();				/* Virtual terminal.	*/
	edinit();				/* Buffers, windows.	*/
	keymapinit();				/* Symbols, bindings.	*/
	/* doing update() before reading files causes the error messages from
	 * the file I/O show up on the screen.  (and also an extra display
	 * of the mode line if there are files specified on the command line.)
	 */
	update();
#ifdef	STARTUP					/* User startup file.	*/
	if ((sfile = startupfile()) != NULL)
		(VOID) load(sfile);
#endif
	while (--argc > 0) {
		adjustcase(*++argv);
                makename(bname, *argv);
		curbp = bfind(bname, TRUE);
		(VOID) showbuffer(curbp, curwp, 0);
		(VOID) readin(*argv);
	}
	lastflag = 0;				/* Fake last flags.	*/
loop:
#ifdef	DPROMPT
	*(promptp = prompt) = '\0';
	if(epresf == KPROMPT) eerase();
#endif
	update();				/* Fix up the screen.	*/
	c = getkey(KPROMPT);
	if (epresf == TRUE)
	{
		eerase();
		update();
	}
	f = FALSE;
	n = 1;
	if (((KMETA|'0') <= c && c <= (KMETA|'9')) || c == (KMETA|'-'))
	{
		f = TRUE;
		c = c & ~KMETA;
	}
	else if (c == (KCTRL|'U'))
	{
		f = TRUE;
		n = 4;
		while ((c=getkey(KNOMAC | KPROMPT)) == (KCTRL|'U')) 
			n *= 4;
	}
	if (f == TRUE)
	{
		if ((c>='0' && c<='9') || c=='-')
		{
			if (c == '-')
			{
				n = 0;
				mflag = TRUE;
			}
			else
			{
				n = ((int) c) - '0';
				mflag = FALSE;
			}
			while ((c=getkey(KNOMAC | KPROMPT))>='0' && c<='9')
				n = 10*n + ((int) c) - '0';
			if (mflag != FALSE)
				n = -n;
		}
	}
	if (kbdmip != NULL)
	{			/* Terminate macros.	*/
		if (c!=(KCTLX|')') && kbdmip>&kbdm[NKBDM-6])
		{
			(VOID) ctrlg(FALSE, 0, KRANDOM);
			goto loop;
		}
		if (f != FALSE)
		{
			kbdmip[-1] = (KEY) (KCTRL|'U');/* overwrite ESC */
			*kbdmip++ = (KEY) n;
			*kbdmip++ = (KEY) c;
		}
	}
	switch (execute(c, f, n))
	{		/* Do it.		*/
		case TRUE: break;
		case ABORT:
			ewprintf("Quit");	/* and fall through */
		case FALSE:
		default:
			ttbeep();
			if (kbdmip != NULL)
			{
				kbdm[0] = (KEY) (KCTLX|')');
				kbdmip = NULL;
			}
	}
	goto loop;
}

/*
 * Command execution. Look up the binding in the the
 * binding array, and do what it says. Return a very bad status
 * if there is no binding, or if the symbol has a type that
 * is not usable (there is no way to get this into a symbol table
 * entry now). Also fiddle with the flags.
 */
execute(c, f, n)
   KEY c;
{
	register SYMBOL	*sp;
	register int	status;

	if ((sp=binding[c]) != NULL)
	{
		thisflag = 0;
		status = (*sp->s_funcp)(f, n, c);
		lastflag = thisflag;
		return (status);
	}
	lastflag = 0;
	return (FALSE);
}

/*
 * Initialize all of the buffers
 * and windows. The buffer name is passed down as
 * an argument, because the main routine may have been
 * told to read in a file by default, and we want the
 * buffer name to be right.
 */
VOID
edinit()
{
	register BUFFER	*bp;
	register WINDOW	*wp;

	bheadp = NULL;
	bp = bfind("*scratch*", TRUE);		/* Text buffer.		*/
	wp = (WINDOW *)malloc(sizeof(WINDOW));	/* Initial window.	*/
	if (bp==NULL || wp==NULL) panic("edinit");
	curbp  = bp;				/* Current ones.	*/
	wheadp = wp;
	curwp  = wp;
	wp->w_wndp  = NULL;			/* Initialize window.	*/
	wp->w_bufp  = bp;
	bp->b_nwnd  = 1;			/* Displayed.		*/
	wp->w_linep = bp->b_linep;
	wp->w_dotp  = bp->b_linep;
	wp->w_doto  = 0;
	wp->w_markp = NULL;
	wp->w_marko = 0;
	wp->w_toprow = 0;
	wp->w_ntrows = nrow-2;			/* 2 = mode, echo.	*/
	wp->w_force = 0;
	wp->w_flag  = WFMODE|WFHARD;		/* Full.		*/
}

/*
 * Quit command. If an argument, always
 * quit. Otherwise confirm if a buffer has been
 * changed and not written out. Normally bound
 * to "C-X C-C".
 */
/*ARGSUSED*/
quit(f, n, k)
{
	register int	s;

	if (f == FALSE)
	{
		if ((s = anycb(FALSE)) == ABORT)
			return ABORT;
		if (s == FALSE
			|| eyesno("The text is modified, really exit") == TRUE)
		{
			vttidy();
			exit(GOOD);
		}
	}
	else
	{
		vttidy();
		exit(GOOD);
	}
	return TRUE;
}


/*
 * User abort. Should be called by any input routine that sees a C-g
 * to abort whatever C-g is aborting these days. Currently does
 * nothing.
 */
/*ARGSUSED*/
ctrlg(f, n, k)
{
	return (ABORT);
}
\Rogue\Monster\
else
  echo "will not over write ./main.c"
fi
if `test ! -s ./match.c`
then
echo "writing ./match.c"
cat > ./match.c << '\Rogue\Monster\'
/*
 * Name:	MicroEMACS
 * 		Limited parenthesis matching routines
 * Version:	Gnu30
 * Last edit:	13-Jul-86
 * Created:	19-May-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
 *
 * The hacks in this file implement automatic matching
 * of (), [], {}, and other characters.  It would be
 * better to have a full-blown syntax table, but there's
 * enough overhead in the editor as it is.
 *
 * Since I often edit Scribe code, I've made it possible to
 * blink arbitrary characters -- just bind delimiter characters
 * to "blink-matching-paren-hack"
 */
#include	"def.h"

#ifndef TINY

static int balance();
static displaymatch();

/* Balance table. When balance() encounters a character
 * that is to be matched, it first searches this table
 * for a balancing left-side character.  If the character
 * is not in the table, the character is balanced by itself.
 * This is to allow delimiters in Scribe documents to be matched.
 */	

static struct balance {
	char left, right;
} bal[] = {
	{ '(', ')' },
	{ '[', ']' },
	{ '{', '}' },
	{ '<', '>' },
	{ '\0','\0'}
};

/*
 * Fake the GNU "blink-matching-paren" variable.
 * If the argument exists, nonzero means show,
 * zero means don't.  If it doesn't exist,
 * pretend it's nonzero.
 */

blinkparen(f, n, k)
{
	register char	*command;
	register SYMBOL	*sp;

	if (f == FALSE)
		n = 1;
	command = (n == 0) ? "self-insert-command" :
			     "blink-matching-paren-hack";
	if ((sp=symlookup(command)) == NULL)
	{
		ewprintf("blinkparen: no binding for %s",command);
		return (FALSE);
	}
	binding[(KEY) ')'] = sp;		/* rebind paren		*/
	return (TRUE);	
}

/*
 * Self-insert character, then show matching character,
 * if any.  Bound to "blink-matching-paren-command".
 */

showmatch(f, n, k)
{
	register int  i, s;

	if (k == KRANDOM)
		return(FALSE);
	for (i = 0; i < n; i++)
	{
		if ((s = selfinsert(f, 1, k)) != TRUE)
			return(s);
		if (balance(k) != TRUE)	/* unbalanced -- warn user */
			ttbeep();
	}
	return (TRUE);
}

/*
 * Search for and display a matching character.
 *
 * This routine does the real work of searching backward
 * for a balancing character.  If such a balancing character
 * is found, it uses displaymatch() to display the match.
 */

static balance(k)
int k;
{
	register LINE	*clp;
	register int	cbo;
	int	c;
	int	i;
	int	rbal, lbal;
	int	depth;

	rbal = k & KCHAR;
	if ((k&KCTRL)!=0 && rbal>='@' && rbal<='_') /* ASCII-ify.	*/
		rbal -= '@';

	/* See if there is a matching character -- default to the same */

	lbal = rbal;
	for (i = 0; bal[i].right != '\0'; i++)
		if (bal[i].right == rbal)
		{
			lbal = bal[i].left;
			break;
		}

	/* Move behind the inserted character.  We are always guaranteed    */
	/* that there is at least one character on the line, since one was  */
	/* just self-inserted by blinkparen.				    */

	clp = curwp->w_dotp;
	cbo = curwp->w_doto - 1;

	depth = 0;			/* init nesting depth		*/

	for (;;)
	{
		if (cbo == 0)
		{			/* beginning of line	*/
			clp = lback(clp);
			if (clp == curbp->b_linep)
				return (FALSE);
			cbo = llength(clp)+1;
		}
		if (--cbo == llength(clp))	/* end of line		*/
			c = '\n';
		else
			c = lgetc(clp,cbo);	/* somewhere in middle	*/

		/* Check for a matching character.  If still in a nested */
		/* level, pop out of it and continue search.  This check */
		/* is done before the nesting check so single-character	 */
		/* matches will work too.				 */
		if (c == lbal)
		{
			if (depth == 0)
			{
				displaymatch(clp,cbo);
				return (TRUE);
			}
			else
				depth--;
		}
		/* Check for another level of nesting.  */
		if (c == rbal)
			depth++;
	}
	/*NOTREACHED*/
}


/*
 * Display matching character.
 * Matching characters that are not in the current window
 * are displayed in the echo line. If in the current
 * window, move dot to the matching character,
 * sit there a while, then move back.
 */

static displaymatch(clp, cbo)
register LINE *clp;
register int  cbo;
{
	register LINE	*tlp;
	register int	tbo;
	register int	cp;
	register int	bufo;
	register int	c;
	int		inwindow;
	char	 	buf[NLINE];

	/* Figure out if matching char is in current window by	*/
	/* searching from the top of the window to dot.		*/

	inwindow = FALSE;
	for (tlp = curwp->w_linep; tlp != lforw(curwp->w_dotp); tlp = lforw(tlp))
		if (tlp == clp)
			inwindow = TRUE;

	if (inwindow == TRUE)
	{
		tlp = curwp->w_dotp;	/* save current position */
		tbo = curwp->w_doto;

		curwp->w_dotp  = clp;	/* move to new position */
		curwp->w_doto  = cbo;
		curwp->w_flag |= WFMOVE;

		update();		/* show match */
		sleep(1);		/* wait a bit */

		curwp->w_dotp   = tlp;	/* return to old position */
		curwp->w_doto   = tbo;
		curwp->w_flag  |= WFMOVE;
		update();
	}
	else
	{	/* match not in this window so display line in echo area */
		bufo = 0;
		for (cp = 0; cp < llength(clp); cp++)
		{	/* expand tabs	*/
			c = lgetc(clp,cp);
                        if (
#ifdef	NOTAB
			    (mode&MNOTAB) ||
#endif
			    c != '\t')
			    	if(ISCTRL(c))
				{
				    buf[bufo++] = '^';
				    buf[bufo++] = c ^ 0x40;
				} else buf[bufo++] = c;
			else
				do {
					buf[bufo++] = ' ';
				} while (bufo & 7);
		}
		buf[bufo++] = '\0';
		ewprintf("Matches %s",buf);
	}
	return (TRUE);
}
#endif
\Rogue\Monster\
else
  echo "will not over write ./match.c"
fi
if `test ! -s ./newlog.c`
then
echo "writing ./newlog.c"
cat > ./newlog.c << '\Rogue\Monster\'
/*************************************************************************
*
*  newlog - set up a header for a new log entry
*
**************************************************************************/

#ifdef MISLOG
#include "def.h"
#include <stdio.h>
#include <pwd.h>
#include <time.h>

int newlog( f, n, k)
   int f, n, k;
{

   FILE *fp, *fopen(); 
   struct passwd *pw_entry, *getpwnam();
   char *fs_file, basename[80], author[80], date[80],
        *getlogin(), *asctime(), *login_name, buf[80],
        *tmpnam();
   struct tm *timenow, *localtime();
   long clock, time();
   int n;

   login_name = getlogin();
   pw_entry = getpwnam(login_name);
   strcpy(author, pw_entry->pw_gecos);

   clock = time((long *) 0);
   timenow = localtime(&clock);

   fs_file = tmpnam();
   fp = fopen(fs_file, "w");
   sprintf(date, "%s", asctime(timenow));
   fprintf(fp,
    "----------------------------------------------------------------------\n");
   date[strlen(date) - 1] = '\0';
   fprintf(fp, "%s         %s\n\n", date, author);

   fclose(fp);
   gotoeob( FALSE, 0, 0);
   insertfile( fs_file, (char *)0);
   unlink( fs_file);
   gotoeob( FALSE, 0, 0);

   return TRUE;
}
#endif
\Rogue\Monster\
else
  echo "will not over write ./newlog.c"
fi
if `test ! -s ./paragraph.c`
then
echo "writing ./paragraph.c"
cat > ./paragraph.c << '\Rogue\Monster\'
/*
 * Code for dealing with paragraphs and filling. Adapted from MicroEMACS 3.6
 * and GNU-ified by mwm at ucbvax.  Several bug fixes by blarson at usc-oberon.
 */
#include "def.h"

static int	fillcol = 70 ;
#define	MAXWORD	256

/*
 * go back to the begining of the current paragraph
 * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
 * combination to delimit the begining of a paragraph
 */
/*ARGSUSED*/
gotobop(f, n, k)
{
	register int suc;	/* success of last backchar */

	if (n < 0)	/* the other way...*/
		return(gotoeop(f, -n, KRANDOM));

	while (n-- > 0)
	{	/* for each one asked for */

		/* first scan back until we are in a word */
		suc = backchar(FALSE, 1, KRANDOM);
		while (!inword() && suc)
			suc = backchar(FALSE, 1, KRANDOM);
		curwp->w_doto = 0;	/* and go to the B-O-Line */

		/* and scan back until we hit a <NL><SP> <NL><TAB> or <NL><NL> */
		while (lback(curwp->w_dotp) != curbp->b_linep)
			if (llength(lback(curwp->w_dotp)) 
			    && lgetc(curwp->w_dotp,0) != ' '
			    && lgetc(curwp->w_dotp,0) != '\t')
				curwp->w_dotp = lback(curwp->w_dotp);
			else
				break;
	}
	curwp->w_flag |= WFMOVE;	/* force screen update */
	return TRUE;
}

/*
 * go forword to the end of the current paragraph
 * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
 * combination to delimit the begining of a paragraph
 */
/*ARGSUSED*/
gotoeop(f, n, k)
{
	register int suc;	/* success of last backchar */

	if (n < 0)	/* the other way...*/
		return(gotobop(f, -n, KRANDOM));

	while (n-- > 0)
	{	/* for each one asked for */

		/* Find the first word on/after the current line */
		curwp->w_doto = 0;
		suc = forwchar(FALSE, 1, KRANDOM);
		while (!inword() && suc)
			suc = forwchar(FALSE, 1, KRANDOM);
		curwp->w_doto = 0;
		if (curwp->w_dotp == curbp->b_linep)
			break;				/* check for eob */
		curwp->w_dotp = lforw(curwp->w_dotp);

		/* and scan forword until we hit a <NL><SP> or ... */
		while (curwp->w_dotp != curbp->b_linep)
		{
			if (llength(curwp->w_dotp)
			    && lgetc(curwp->w_dotp,0) != ' '
			    && lgetc(curwp->w_dotp,0) != '\t')
				curwp->w_dotp = lforw(curwp->w_dotp);
			else
				break;
		}
	}
	curwp->w_flag |= WFMOVE;	/* force screen update */
	return TRUE;
}

/*
 * Fill the current paragraph according to the current
 * fill column
 */
/*ARGSUSED*/
fillpara(f, n, k)
{
	register int	c;		/* current char durring scan	*/
	register int	wordlen;	/* length of current word	*/
	register int	clength;	/* position on line during fill	*/
	register int	i;		/* index during word copy	*/
	register int	eopflag;	/* Are we at the End-Of-Paragraph? */
	int	 	firstflag;	/* first word? (needs no space)	*/
	int		newlength;	/* tentative new line length	*/
	int		eolflag;	/* was at end of line		*/
	LINE	 	*eopline;	/* pointer to line just past EOP */
	char wbuf[MAXWORD];		/* buffer for current word	*/
	int		old_mode;	/* saved mode value		*/

	/* save the mode and put into insert mode for duration of fill */
	old_mode = mode;
	mode &= !MOVRSTK;

	/* record the pointer to the line just past the EOP */
	(VOID) gotoeop(FALSE, 1, KRANDOM);
	eopline = curwp->w_dotp;

	/* and back top the begining of the paragraph */
	(VOID) gotobop(FALSE, 1, KRANDOM);

	/* initialize various info */
	i = TRUE;
	while (i == TRUE && !inword())
		i = forwchar(FALSE, 1, KRANDOM);
	clength = curwp->w_doto;
	wordlen = 0;

	/* scan through lines, filling words */
	firstflag = TRUE;
	eopflag = FALSE;
	while (!eopflag)
	{
		/* get the next character in the paragraph */
		if (eolflag=(curwp->w_doto == llength(curwp->w_dotp)))
		{
			c = ' ';
			if (lforw(curwp->w_dotp) == eopline)
				eopflag = TRUE;
		} else
			c = lgetc(curwp->w_dotp, curwp->w_doto);

		/* and then delete it */
		if (ldelete((RSIZE) 1, KNONE) == FALSE)
		{
			mode = old_mode;
			return FALSE ;
		}

		/* if not a separator, just add it in */
		if (c != ' ' && c != '\t')
		{
			if (wordlen < MAXWORD - 1)
				wbuf[wordlen++] = c;
			else
			{
				/* You loose chars beyond MAXWORD if the word
				 * is to long. I'm to lazy to fix it now; it
				 * just silently truncated the word before, so
				 * I get to feel smug.
				 */
				ewprintf("Word too long!");
			}
		}
		else if (wordlen)
		{
			/* calculate tenatitive new length with word added */
			newlength = clength + 1 + wordlen;
			/* if at end of line or at doublespace and previous
			 * character was one of '.','?','!' doublespace here.
			 */
			if((eolflag || curwp->w_doto==llength(curwp->w_dotp)
				|| (c=lgetc(curwp->w_dotp,curwp->w_doto))==' '
				|| c=='\t')
			      && ISEOSP(wbuf[wordlen-1])
			      && wordlen<MAXWORD-1)
				wbuf[wordlen++] = ' ';
			/* at a word break with a word waiting */
 			if (newlength <= fillcol)
			{
				/* add word to current line */
				if (!firstflag)
				{
					(VOID) linsert((RSIZE) 1, ' ');
					++clength;
				}
				firstflag = FALSE;
			}
			else
			{
				if(curwp->w_doto > 0 &&
					lgetc(curwp->w_dotp,curwp->w_doto-1)==' ')
				{
				    	curwp->w_doto -= 1;
					(VOID) ldelete((RSIZE) 1, KNONE);
				}
				/* start a new line */
				(VOID) lnewline();
				clength = 0;
			}

			/* and add the word in in either case */
			for (i=0; i<wordlen; i++)
			{
				(VOID) linsert((RSIZE) 1, wbuf[i]);
				++clength;
			}
			wordlen = 0;
		}
	}
	/* and add a last newline for the end of our new paragraph */
	(VOID) lnewline();
	/* we realy should wind up where we started, (which is hard to keep
	 * track of) but I think the end of the last line is better than the
	 * begining of the blank line.	 */
	(VOID) backchar(FALSE, 1, KRANDOM);
	mode = old_mode;
	return TRUE;
}

/* delete n paragraphs starting with the current one */
/*ARGSUSED*/
killpara(f, n, k)
{
	register int status;	/* returned status of functions */

	while (n--)
	{		/* for each paragraph to delete */

		/* mark out the end and begining of the para to delete */
		(VOID) gotoeop(FALSE, 1, KRANDOM);

		/* set the mark here */
	        curwp->w_markp = curwp->w_dotp;
	        curwp->w_marko = curwp->w_doto;

		/* go to the begining of the paragraph */
		(VOID) gotobop(FALSE, 1, KRANDOM);
		curwp->w_doto = 0;	/* force us to the begining of line */
	
		/* and delete it */
		if ((status = killregion(FALSE, 1, KRANDOM)) != TRUE)
			return(status);

		/* and clean up the 2 extra lines */
		(VOID) ldelete((RSIZE) 1, KFORW);
	}
	return(TRUE);
}

/*
 * check to see if we're past fillcol, and if so,
 * justify this line. As a last step, justify the line.
 */
/*ARGSUSED*/
fillword(f, n, k)
{
	register char	c;
	register int	col, i, nce;

	for (i = col = 0; col <= fillcol; ++i, ++col)
	{
		if (i == curwp->w_doto) return selfinsert(f, n, k) ;
		c = lgetc(curwp->w_dotp, i);
		if (
#ifdef	NOTAB
		    !(mode&MNOTAB) &&
#endif
		    c == '\t') col |= 0x07;
		else if (ISCTRL(c) != FALSE) ++col;
	}
	if (curwp->w_doto != llength(curwp->w_dotp))
	{
		(VOID) selfinsert(f, n, k);
		nce = llength(curwp->w_dotp) - curwp->w_doto;
	}
	else nce = 0;
	curwp->w_doto = i;

	if ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t')
		do {
			(VOID) backchar(FALSE, 1, KRANDOM);
		} while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
		      && c != '\t' && curwp->w_doto > 0);

	if (curwp->w_doto == 0)
		do {
			(VOID) forwchar(FALSE, 1, KRANDOM);
		} while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
		      && c != '\t' && curwp->w_doto < llength(curwp->w_dotp));

	(VOID) delwhite(FALSE, 1, KRANDOM);
	(VOID) lnewline();
	curwp->w_doto = llength(curwp->w_dotp) - nce;
	curwp->w_flag |= WFMOVE;
	if (nce == 0 && curwp->w_doto != 0) return fillword(f, n, k);
	return TRUE;
}

/* Set fill column to n. */
/*ARGSUSED*/
setfillcol(f, n, k)
{
	extern int	getcolpos() ;

	fillcol = ((f == FALSE) ? getcolpos() : n);
	if (kbdmop == NULL)
		ewprintf("Fill column set to %d", fillcol);
        return(TRUE);
}
\Rogue\Monster\
else
  echo "will not over write ./paragraph.c"
fi
if `test ! -s ./prefix.c`
then
echo "writing ./prefix.c"
cat > ./prefix.c << '\Rogue\Monster\'
/*
 * This code is a kludge for the two prefix sequences from GNU (well,
 * the two I want) that uemacs doesn't have. Rather than quadruple the table
 * space for keys, plus have to test for them everywhere, I'll just kludge
 * it with functions that are bound to those keys. Later, maybe I'll do
 * prefixes right.
 */

#include "def.h"

#ifndef TINY
/*ARGSUSED*/
ctlx4hack(f, n, k)
{
	register KEY	c;

	if ((c = getkey(KPROMPT)) == 'b' || c == 'B')
		return poptobuffer(f, n, KRANDOM);
	if (c == 'f' || c == (KCTRL|'F') || c == 'F')
		return poptofile(f, n, KRANDOM);
	
	if (c == (KCTRL|'G') || c == (KCTLX|KCTRL|'G')
			||  c == (KMETA|KCTRL|'G'))
	{
		(VOID) ctrlg(FALSE, 1, KRANDOM);
		return ABORT;
	}
	return FALSE;
}

/*ARGSUSED*/
help(f, n, k)
{
	register KEY	c;

	c = getkey(KPROMPT);
	while (c == (KCTRL|'H'))
	{
		ewprintf("B C: ");
		c = getkey(0);
	}
	if (c == 'b' || c == 'B')
		return wallchart(f, n, KRANDOM);
	if (c == 'c' || c == 'C')
		return desckey(f, n, KRANDOM);

	if (c == (KCTRL|'G') || c == (KCTLX|KCTRL|'G')
			||  c == (KMETA|KCTRL|'G'))
	{
		(VOID) ctrlg(FALSE, 1, KRANDOM);
		return ABORT;
	}
	return FALSE;
}
#endif
\Rogue\Monster\
else
  echo "will not over write ./prefix.c"
fi
if `test ! -s ./random.c`
then
echo "writing ./random.c"
cat > ./random.c << '\Rogue\Monster\'
/*
 *		Assorted commands.
 * The file contains the command
 * processors for a large assortment of unrelated
 * commands. The only thing they have in common is
 * that they are all command processors.
 */
#include	"def.h"

/*
 * Display a bunch of useful information about
 * the current location of dot. The character under the
 * cursor (in octal), the current line, row, and column, and
 * approximate position of the cursor in the file (as a percentage)
 * is displayed. The column position assumes an infinite position
 * display; it does not truncate just because the screen does.
 * This is normally bound to "C-X =".
 */
/*ARGSUSED*/
showcpos(f, n, k)
{
	register LINE	*clp;
	register long	nchar;
	long		cchar;
	register int	nline, row;
	int		cline, cbyte;	/* Current line/char/byte */
	int		ratio;
	KEY		keychar();

	clp = lforw(curbp->b_linep);		/* Collect the data.	*/
	nchar = 0;
	nline = 0;
	for (;;)
	{
		++nline;			/* Count this line	*/
		if (clp == curwp->w_dotp)
		{
			cline = nline;		/* Mark line		*/
			cchar = nchar + curwp->w_doto;
			if (curwp->w_doto == llength(clp))
				cbyte = '\n';
			else
				cbyte = lgetc(clp, curwp->w_doto);
		}
		nchar += llength(clp) + 1;	/* Now count the chars	*/
		if (clp == curbp->b_linep) break ;
		clp = lforw(clp);
	}
	row = curwp->w_toprow;			/* Determine row.	*/
	clp = curwp->w_linep;
	while (clp!=curbp->b_linep && clp!=curwp->w_dotp)
	{
		++row;
		clp = lforw(clp);
	}
	++row;					/* Convert to origin 1.	*/
	/*NOSTRICT*/	
	/* nchar can't be zero (because of the "bonus" \n at end of file) */
	ratio = (100L*cchar) / nchar;
	ewprintf("Char: %c (0%o)  point=%ld(%d%%)  line=%d  row=%d  col=%d",
		(int) keychar(cbyte, FALSE), cbyte, cchar, ratio, cline, row,
		getcolpos());
	return (TRUE);
}

getcolpos()
{
	register int	col, i, c;

	col = 0;				/* Determine column.	*/
	for (i=0; i<curwp->w_doto; ++i)
	{
		c = lgetc(curwp->w_dotp, i);
		if (
#ifdef	NOTAB
		    !(mode & MNOTAB) &&
#endif
		    c == '\t')
			col |= 0x07;
		else if (ISCTRL(c) != FALSE)
			++col;
		++col;
	}
	return col + 1;				/* Convert to origin 1.	*/
}


/*
 * Ordinary text characters are bound to this function,
 * which inserts them into the buffer. Characters marked as control
 * characters (using the CTRL flag) may be remapped to their ASCII
 * equivalent. This makes TAB (C-I) work right, and also makes the
 * world look reasonable if a control character is bound to this
 * this routine by hand. Any META or CTLX flags on the character
 * are discarded. This is the only routine that actually looks
 * the the "k" argument.
 */
/*ARGSUSED*/
selfinsert(f, n, k)
{
	register int	c;

	if (n < 0)
		return (FALSE);
	if (n == 0)
		return (TRUE);
	c = k & KCHAR;
	if ((k&KCTRL)!=0 && c>='@' && c<='_')	/* ASCII-ify.		*/
		c -= '@';
	return (linsert((RSIZE) n, c));
}

/*
 * Open up some blank space. The basic plan
 * is to insert a bunch of newlines, and then back
 * up over them. Everything is done by the subcommand
 * procerssors. They even handle the looping. Normally
 * this is bound to "C-O".
 */
/*ARGSUSED*/
openline(f, n, k)
{
	register int	i;
	register int	s;

	if (n < 0)
		return (FALSE);
	if (n == 0)
		return (TRUE);
	gotobol( FALSE, 0, KRANDOM);
	i = n;					/* Insert newlines.	*/
	do {
		s = lnewline();
	} while (s==TRUE && --i);
	if (s == TRUE)				/* Then back up overtop	*/
		s = backchar(f, n, KRANDOM);	/* of them all.		*/
	return (s);
}

/*
 * Insert a newline.
 * If you are at the end of the line and the
 * next line is a blank line, just move into the
 * blank line. This makes "C-O" and "C-X C-O" work
 * nicely, and reduces the ammount of screen
 * update that has to be done. This would not be
 * as critical if screen update were a lot
 * more efficient.
 */
/*ARGSUSED*/
newline(f, n, k)
{
	register LINE	*lp;
	register int	s;

	if (n < 0)
		return (FALSE);
	while (n--)
	{
		lp = curwp->w_dotp;
		if (llength(lp) == curwp->w_doto
		&& lp != curbp->b_linep
		&& llength(lforw(lp)) == 0)
		{
			if ((s=forwchar(FALSE, 1, KRANDOM)) != TRUE)
				return (s);
		} else if ((s=lnewline()) != TRUE)
			return (s);
	}
	return (TRUE);
}


/*
 * Delete any whitespace around dot.
 */
/*ARGSUSED*/
delwhite(f, n, k)
{
	register int	col, c, s;

	col = curwp->w_doto;
	while ((c = lgetc(curwp->w_dotp, col)) == ' ' || c == '\t')
		++col;
	do
		if ((s = backchar(FALSE, 1, KRANDOM)) == FALSE) break;
	while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' ' || c == '\t') ;

	if (s == TRUE) (VOID) forwchar(FALSE, 1, KRANDOM);
	(VOID) ldelete((RSIZE)(col - curwp->w_doto), KNONE);
	return (TRUE);
}


/*
 * Delete forward. This is real
 * easy, because the basic delete routine does
 * all of the work. Watches for negative arguments,
 * and does the right thing. If any argument is
 * present, it kills rather than deletes, to prevent
 * loss of text if typed with a big argument.
 * Normally bound to "C-D".
 */
/*ARGSUSED*/
forwdel(f, n, k)
{
	if (n < 0)
		return (backdel(f, -n, KRANDOM));
	if (f != FALSE)
	{			/* Really a kill.	*/
		if ((lastflag&CFKILL) == 0)
			kdelete();
		thisflag |= CFKILL;
	}
	return (ldelete((RSIZE) n, f ? KFORW : KNONE));
}

/*
 * Delete backwards. This is quite easy too,
 * because it's all done with other functions. Just
 * move the cursor back, and delete forwards.
 * Like delete forward, this actually does a kill
 * if presented with an argument.
 */
/*ARGSUSED*/
backdel(f, n, k)
{
	register int	s;

	if (n < 0)
		return (forwdel(f, -n, KRANDOM));
	if (f != FALSE)
	{			/* Really a kill.	*/
		if ((lastflag&CFKILL) == 0)
			kdelete();
		thisflag |= CFKILL;
	}
	if ((s=backchar(f, n, KRANDOM)) == TRUE)
		s = ldelete((RSIZE) n, f ? KFORW : KNONE);
	return (s);
}

/*
 * Kill line. If called without an argument,
 * it kills from dot to the end of the line, unless it
 * is at the end of the line, when it kills the newline.
 * If called with an argument of 0, it kills from the
 * start of the line to dot. If called with a positive
 * argument, it kills from dot forward over that number
 * of newlines. If called with a negative argument it
 * kills any text before dot on the current line,
 * then it kills back abs(arg) lines.
 */
/*ARGSUSED*/
killline(f, n, k)
{
	register RSIZE	chunk;
	register LINE	*nextp;
	register int	i, c;

	if ((lastflag&CFKILL) == 0)		/* Clear kill buffer if	*/
		kdelete();			/* last wasn't a kill.	*/
	thisflag |= CFKILL;
	if (f == FALSE)
	{
		for (i = curwp->w_doto; i < llength(curwp->w_dotp); ++i)
			if ((c = lgetc(curwp->w_dotp, i)) != ' ' && c != '\t')
				break;
		if (i == llength(curwp->w_dotp))
			chunk = llength(curwp->w_dotp)-curwp->w_doto + 1;
		else
		{
			chunk = llength(curwp->w_dotp)-curwp->w_doto;
			if (chunk == 0)
				chunk = 1;
		}
	}
	else if (n > 0)
	{
		chunk = llength(curwp->w_dotp)-curwp->w_doto+1;
		nextp = lforw(curwp->w_dotp);
		i = n;
		while (--i)
		{
			if (nextp == curbp->b_linep)
				break;
			chunk += llength(nextp)+1;
			nextp = lforw(nextp);
		}
	}
	else
	{				/* n <= 0		*/
		chunk = curwp->w_doto;
		curwp->w_doto = 0;
		i = n;
		while (i++)
		{
			if (lback(curwp->w_dotp) == curbp->b_linep)
				break;
			curwp->w_dotp = lback(curwp->w_dotp);
			curwp->w_flag |= WFMOVE;
			chunk += llength(curwp->w_dotp)+1;
		}
	}
	/*
	 * KFORW here is a bug. Should be KBACK/KFORW, but we need to
	 * rewrite the ldelete code (later)?
	 */
	return (ldelete(chunk,  KFORW));
}


/*
 * Commands to toggle the five modes. Without an argument, sets the
 * mode on, with an argument, sets the mode off.
 */
/*ARGSUSED*/
bsmapmode(f, n, k)
{

	if ((mode&MBSMAP) != MBSMAP)
		mode |= MBSMAP;
	else
		mode &= ~MBSMAP;
	upmodes((BUFFER *) NULL);
	return TRUE;
}

/*ARGSUSED*/
flowmode(f, n, k)
{
	if ((mode&MFLOW) != MFLOW)
		mode |= MFLOW;
	else
		mode &= ~MFLOW;
	upmodes((BUFFER *) NULL);
	return TRUE;
}


/*ARGSUSED*/
fillmode(f, n, k)
{

	if ((mode&MFILL) != MFILL)
	{
		mode |= MFILL;
		if ((binding[' '] = symlookup("insert-with-wrap")) == NULL)
			panic("no insert-with-wrap in fillmode");
	} else
	{
		mode &= ~MFILL;
		if ((binding[' '] = symlookup("self-insert-command")) == NULL)
			panic("no self-insert-command in fillmode");
	}
	upmodes((BUFFER *) NULL);
	return TRUE;
}
#ifdef  NOTAB

space_tabpos(f, n, k)
int f, n;
{
	int stat;

	if(n<0)
		return FALSE;
	if(n==0)
		return TRUE;
	return linsert(((RSIZE)n<<3) - (curwp->w_doto & 7), ' ');
}

notabmode(f, n, k)
{
	if((mode&MNOTAB) != MNOTAB)
	{
		mode |= MNOTAB;
		if ((binding[KCTRL|'I'] = symlookup("space-to-tabstop")) == NULL)
			panic("no space-to-tabstop in notabmode");
	}
	else
	{
		mode &= ~ MNOTAB;
		if ((binding[KCTRL|'I'] = symlookup("self-insert-command")) == NULL)
			panic("no self-insert-command in notabmode");
	}
	upmodes((BUFFER *) NULL);
	return TRUE;
}
#endif

/*
 * This function toggles the state of the 
 * insert/overstrike flag.  The editor will come up in
 * one mode or the other, and can be changed by this
 * function. No argument or 0 will toggle the value, >0 will
 * set to insert mode, <0 will set to overstrike.
 */
/*ARGSUSED*/
insovrmode( f, n, k)
{
	if (f == FALSE || n == 0)
	{
		if ((mode & MOVRSTK) == MOVRSTK)
			mode &= ~MOVRSTK;
		else
			mode |= MOVRSTK;
	}
	else if (n > 0)
		mode &= ~MOVRSTK;
	else
		mode |= MOVRSTK;

	upmodes((BUFFER *) NULL);
	return TRUE;
}

/*
 * Yank text back from the kill buffer. This
 * is really easy. All of the work is done by the
 * standard insert routines. All you do is run the loop,
 * and check for errors. The blank
 * lines are inserted with a call to "newline"
 * instead of a call to "lnewline" so that the magic
 * stuff that happens when you type a carriage
 * return also happens when a carriage return is
 * yanked back from the kill buffer.
 * An attempt has been made to fix the cosmetic bug
 * associated with a yank when dot is on the top line of
 * the window (nothing moves, because all of the new
 * text landed off screen).
 */
/*ARGSUSED*/
yank(f, n, k)
{
	register int	c;
	register int	i;
	register LINE	*lp;
	register int	nline;

	if (n < 0)
		return (FALSE);
	nline = 0;				/* Newline counting.	*/
	while (n--) {
		isetmark();			/* mark around last yank */
		i = 0;
		while ((c=kremove(i)) >= 0) {
			if (c == '\n') {
				if (newline(FALSE, 1, KRANDOM) == FALSE)
					return (FALSE);
				++nline;
			} else {
				if (linsert((RSIZE) 1, c) == FALSE)
					return (FALSE);
			}
			++i;
		}
	}
	lp = curwp->w_linep;			/* Cosmetic adjustment	*/
	if (curwp->w_dotp == lp) {		/* if offscreen insert.	*/
		while (nline-- && lback(lp)!=curbp->b_linep)
			lp = lback(lp);
		curwp->w_linep = lp;		/* Adjust framing.	*/
		curwp->w_flag |= WFHARD;
	}
	return (TRUE);
}

\Rogue\Monster\
else
  echo "will not over write ./random.c"
fi
echo "Finished archive 2 of 5"
exit
-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Mark A. Hargrove                                             U.S. TeleCenters
Voice: 408-496-1800                                          Santa Clara, CA
uucp : {dual, hoptoad, hplabs, portal, ptsfa}!well!ustel



More information about the Comp.sources.misc mailing list