Vile 07/17 - vi feel-alike (multi-window)

Paul Fox pgf at cayman.COM
Sat Jun 8 08:09:37 AEST 1991


#!/bin/sh
# this is vileshar.07 (part 7 of Vile)
# do not concatenate these parts, unpack them in order with /bin/sh
# file file.c continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 7; then
	echo Please unpack part "$Scheck" next!
	exit 1
 else
	exit 0
 fi
) < _shar_seq_.tmp || exit 1
echo 'x - continuing file file.c'
sed 's/^X//' << 'SHAR_EOF' >> 'file.c' &&
X
#ifdef BEFORE
X        if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE)
X                return s;
X	if ((s = glob(fname)) != TRUE)
X		return FALSE;
#else
X	if (isnamedcmd && lastkey == '\r') {
X		strncpy(fname, curbp->b_fname, NFILEN);
X
X		if (mlyesno("Okay to write [possible] partial range") != TRUE) {
X			mlwrite("Range not written");
X			return FALSE;
X		}
X	} else {
X		/* HACK -- this implies knowledge of 
X					how kbd_engl works! */
X	        if ((s=mlreply("Write region to file: ", fname, NFILEN))
X							 != TRUE)
X	                return s;
X		if ((s = glob(fname)) != TRUE)
X			return FALSE;
X		if (strcmp(fname,curbp->b_fname) &&
X			fname[0] != '!' && flook(fname,FL_HERE)) {
X			if (mlyesno("File exists, okay to overwrite")
X							!= TRUE) {
X				mlwrite("File not written");
X				return FALSE;
X			}
X		}
X        }
#endif
X        if ((s=getregion(&region,NULL)) != TRUE)
X                return s;
#if DOSFILES
X	dosfile = curbp->b_mode & MDDOS;
#endif
X	s = writereg(&region,fname,TRUE);
X        return s;
}
X
X
writereg(rp,fn,msgf)
REGION *rp;
char    *fn;
{
X        register int    s;
X        register LINE   *lp;
X        register int    nline;
X	register int i;
X	long lim;
X	long nchar;
X
#if	CRYPT
X	s = resetkey(curbp);
X	if (s != TRUE)
X		return s;
#endif
X        if (*fn == '[' || *fn == ' ') {
X        	mlwrite("No filename");
X        	return FALSE;
X        }
X        
X        if ((s=ffwopen(fn)) != FIOSUC)       /* Open writes message. */
X                return FALSE;
X
X	/* tell us we're writing */
X	if (msgf == TRUE)
X		mlwrite("[Writing...]");
X
#if UNIX & ! NeWS
X	if (fileispipe)
X		ttclean(TRUE);
#else
X	TTkclose();
#endif
X
X        lp = rp->r_linep;
X        nline = 0;                              /* Number of lines     */
X        nchar = 0;                              /* Number of chars     */
X
X	/* First and maybe only line. */
X	if (rp->r_offset <= llength(lp)) {
X		if ((lim = rp->r_offset+rp->r_size) > llength(lp))
X			lim = (long)llength(lp);
X		for (i = rp->r_offset; i < lim; i++) {
X		        if ((s=ffputc(lgetc(lp,i))) != FIOSUC)
X		                goto out;
X			nchar++;
X		}
X		rp->r_size -= nchar;
X
X		if (rp->r_size <= 0)
X			goto out;
X
X	        if ((s=ffputc('\n')) != FIOSUC)
X	                goto out;
X
X		nchar++;
X		nline++;
X		rp->r_size--;
X                lp = lforw(lp);
X
X	}
X
X	/* whole lines */
X        while (rp->r_size >= llength(lp)+1) {
X                if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
X                        goto out;
X                ++nline;
X		nchar += llength(lp) + 1;
X		rp->r_size -= llength(lp) + 1;
X                lp = lforw(lp);
X        }
X
X	/* last line */
X	if (rp->r_size > 0) {
X		lim = rp->r_size;
X		for (i = 0; i < lim; i++) {
X		        if ((s=ffputc(lgetc(lp,i))) != FIOSUC)
X		                goto out;
X			nchar++;
X			rp->r_size--;
X		}
X	}
X	if (rp->r_size != 0)
X		mlwrite("Bug: writereg, rsize == %d",rp->r_size);
X
X out:
X        if (s == FIOSUC) {                      /* No write error.      */
X                s = ffclose();
X                if (s == FIOSUC && msgf) {      /* No close error.      */
X	                mlwrite("[Wrote %d line%s %d char%s to %s]", 
X				nline, (nline>1)?"s":"",
X				nchar, (nchar>1)?"s":"", fn);
X                }
X        } else {                                /* Ignore close error   */
X                ffclose();                      /* if a write error.    */
X	}
#if UNIX & ! NeWS
X	if (fileispipe == TRUE) {
X		ttunclean();
X	        TTflush();
X		sgarbf = TRUE;
X		pressreturn();
X	}
#else
X	TTkopen();
#endif
X        if (s != FIOSUC)                        /* Some sort of error.  */
X                return FALSE;
X        return TRUE;
}
X
/*
X * This function writes the kill register to a file
X * Uses the file management routines in the
X * "fileio.c" package. The number of lines written is
X * displayed.
X */
kwrite(fn,msgf)
char    *fn;
{
X	register KILL *kp;		/* pointer into kill register */
X	register int	nline;
X	register int	s;
X	register int	c;
X	register int	i;
X	register char	*sp;	/* pointer into string to insert */
X
X	/* make sure there is something to put */
X	if (kbs[ukb].kbufh == NULL) {
X		if (msgf) mlwrite("Nothing to write");
X		return FALSE;		/* not an error, just nothing */
X	}
X
#if	CRYPT
X	s = resetkey(curbp);
X	if (s != TRUE)
X		return s;
#endif
X	/* turn off ALL keyboard translation in case we get a dos error */
X	TTkclose();
X
X	if ((s=ffwopen(fn)) != FIOSUC) {	/* Open writes message. */
X		TTkopen();
X		return FALSE;
X	}
X	/* tell us we're writing */
X	if (msgf == TRUE)
X		mlwrite("[Writing...]");
X	nline = 0;				/* Number of lines.	*/
X
X	kp = kbs[ukb].kbufh;
X	while (kp != NULL) {
X		if (kp->d_next == NULL)
X			i = kbs[ukb].kused;
X		else
X			i = KBLOCK;
X		sp = kp->d_chunk;
X		while (i--) {
X			if ((c = *sp++) == '\n')
X				nline++;
X			if ((s = ffputc(c)) != FIOSUC)
X				break;
X		}
X		kp = kp->d_next;
X	}
X	if (s == FIOSUC) {			/* No write error.	*/
X		s = ffclose();
X		if (s == FIOSUC && msgf) {	/* No close error.	*/
X			mlwrite("[Wrote %d line%s to %s ]",
X					nline,nline!=1?"s":"", fn);
X		}
X	} else	{				/* Ignore close error	*/
X		ffclose();			/* if a write error.	*/
X	}
X	TTkopen();
X	if (s != FIOSUC)			/* Some sort of error.	*/
X		return FALSE;
X	return TRUE;
}
X
X
/*
X * The command allows the user
X * to modify the file name associated with
X * the current buffer. It is like the "f" command
X * in UNIX "ed". The operation is simple; just zap
X * the name in the BUFFER structure, and mark the windows
X * as needing an update. You can type a blank line at the
X * prompt if you wish.
X */
filename(f, n)
{
X        register int    s;
X        static char            fname[NFILEN];
X
X        if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT)
X                return s;
X	if ((s = glob(fname)) != TRUE)
X		return FALSE;
X        if (s == FALSE)
X                strcpy(curbp->b_fname, "");
X        else
X                strcpy(curbp->b_fname, fname);
X	curbp->b_mode &= ~MDVIEW;	/* no longer read only mode */
X	markWFMODE(curbp);
X        return TRUE;
}
X
/*
X * Insert file "fname" into the current
X * buffer, Called by insert file command. Return the final
X * status of the read.
X */
ifile(fname,belowthisline,haveffp)
char    fname[];
FILE *haveffp;
{
X        register LINE   *lp0;
X        register LINE   *lp1;
X        register LINE   *lp2;
X        register int    i;
X        register BUFFER *bp;
X        register int    s;
X        int    nbytes;
X        register int    nline;
X	char mesg[NSTRING];
X	extern FILE	*ffp;
X
X        bp = curbp;                             /* Cheap.               */
X        bp->b_flag |= BFCHG;			/* we have changed	*/
X	bp->b_flag &= ~BFINVS;			/* and are not temporary*/
X	if (!haveffp) {
X	        if ((s=ffropen(fname)) == FIOERR)       /* Hard file open.      */
X	                goto out;
X	        if (s == FIOFNF) {                      /* File not found.      */
X	                mlwrite("[No such file \"%s\" ]", fname);
X			return FALSE;
X	        }
X	        mlwrite("[Inserting...]");
#if UNIX
X		if (fileispipe)
X			ttclean(TRUE);
#endif
X
#if	CRYPT
X		s = resetkey(curbp);
X		if (s != TRUE)
X			return s;
#endif
X	} else { /* we already have the file pointer */
X		ffp = haveffp;
X	}
X	lp0 = curwp->w_dotp;
X	curwp->w_doto = 0;
X	setmark();
X
X	nline = 0;
X	while ((s=ffgetline(&nbytes)) == FIOSUC) {
X		if ((lp1=lalloc(nbytes)) == NULL) {
X			s = FIOMEM;		/* Keep message on the	*/
X			break;			/* display.		*/
X		}
X		if (belowthisline) {
X			lp2 = lp0->l_fp;	/* line after insert */
X		} else {
X			lp2 = lp0;
X			lp0 = lp0->l_bp;
X		}
X
X		/* re-link new line between lp0 and lp2 */
X		lp2->l_bp = lp1;
X		lp0->l_fp = lp1;
X		lp1->l_bp = lp0;
X		lp1->l_fp = lp2;
X
#if BEFORE
X		/* and advance and write out the current line */
X		curwp->w_dotp = lp1;
#endif
#if BEFORE
X		for (i=0; i<nbytes; ++i)
X			lputc(lp1, i, fline[i]);
#else
X		memcpy(lp1->l_text, fline, nbytes);
#endif
#if BEFORE
X		curwp->w_dotp = curwp->w_mkp;
#endif
X		tag_for_undo(lp1);
X		if (belowthisline)
X			lp0 = lp1;
X		else
X			lp0 = lp2;
X		++nline;
X	}
X	if (!haveffp) {
#if UNIX
X		if (fileispipe == TRUE) {
X			ttunclean();
X			TTflush();
X			sgarbf = TRUE;
X		}
#endif
X		ffclose();				/* Ignore errors.	*/
X		readlinesmsg(nline,s,fname,FALSE);
X	}
#if BEFORE
X	curwp->w_mkp = lforw(curwp->w_mkp);
#endif
out:
X	/* advance to the next line and mark the window for changes */
X	curwp->w_dotp = lforw(curwp->w_dotp);
X	curwp->w_flag |= WFHARD | WFMODE;
X
X	/* copy window parameters back to the buffer structure */
X	curbp->b_dotp = curwp->w_dotp;
X	curbp->b_doto = curwp->w_doto;
X	curbp->b_markp = curwp->w_mkp;
X	curbp->b_marko = curwp->w_mko;
X	curbp->b_ldmkp = curwp->w_ldmkp;
X	curbp->b_ldmko = curwp->w_ldmko;
X
X        if (s == FIOERR)                        /* False if error.      */
X                return FALSE;
X        return TRUE;
}
X
/*
X * Insert file "fname" into the kill register
X * Called by insert file command. Return the final
X * status of the read.
X */
kifile(fname)
char    fname[];
{
X        register int    i;
X        register int    s;
X        register int    nline;
X        int    nbytes;
X
X	kdelete();
X        if ((s=ffropen(fname)) == FIOERR)       /* Hard file open.      */
X                goto out;
X        if (s == FIOFNF) {                      /* File not found.      */
X                mlwrite("[No such file \"%s\"]", fname);
X		return FALSE;
X        }
X        mlwrite("[Reading...]");
X
#if UNIX
X	if (fileispipe)
X		ttclean(TRUE);
#endif
X
#if	CRYPT
X	s = resetkey(curbp);
X	if (s != TRUE)
X		return s;
#endif
X        nline = 0;
X        while ((s=ffgetline(&nbytes)) == FIOSUC) {
X                for (i=0; i<nbytes; ++i)
X                        kinsert(fline[i]);
X                kinsert('\n');
X                ++nline;
X        }
#if UNIX
X	if (fileispipe == TRUE) {
X		ttunclean();
X	        TTflush();
X	        sgarbf = TRUE;
X	}
#endif
X        ffclose();                              /* Ignore errors.       */
X	readlinesmsg(nline,s,fname,FALSE);
X
out:
X        if (s == FIOERR)                        /* False if error.      */
X                return FALSE;
X        return TRUE;
}
X
#if UNIX
X
/* called on hangups, interrupts, and quits */
/* This code is definitely not production quality, or probably very
X	robust, or probably very secure.  I whipped it up to save
X	myself while debugging...		pgf */
imdying(signo)
{
#if HAVE_MKDIR
X	static char dirnam[NSTRING] = "/tmp/vileDXXXXXX";
#else
X	static char dirnam[NSTRING] = "/tmp";
#endif
X	char filnam[50];
X	char cmd[80];
X	BUFFER *bp;
X	char *np;
X	int wrote = 0;
X	int created = 0;
X	char *getenv();
X	char *mktemp();
X
X
X	bp = bheadp;
X	while (bp != NULL) {
X		if (((bp->b_flag & BFINVS) == 0) && 
X			 bp->b_active == TRUE && 
X	                 (bp->b_flag&BFCHG) != 0) {
#if HAVE_MKDIR
X			if (!created) {
X				(void)mktemp(dirnam);
X				if(mkdir(dirnam,0700) != 0) {
X					vttidy(FALSE);
X					exit(1);
X				}
X				created = 1;
X			}
#endif
X			strcpy(filnam,dirnam);
X			strcat(filnam,"/");
#if ! HAVE_MKDIR
X			strcat(filnam,"V");
#endif
X			strcat(filnam,bp->b_bname);
X			if (writeout(filnam,bp,FALSE) != TRUE) {
X				vttidy(FALSE);
X				exit(1);
X			}
X			wrote++;
X		}
X		bp = bp->b_bufp;
X	}
X	if (wrote) {
X		if ((np = getenv("LOGNAME")) || (np = getenv("USER"))) {
X			sprintf(cmd,
#if HAVE_MKDIR
X    "(echo Subject: vile died; echo Files saved: ; ls %s/* ) | /bin/mail %s",
#else
X    "(echo Subject: vile died; echo Files saved: ; ls %s/V* ) | /bin/mail %s",
#endif
X				dirnam, np);
X			system(cmd);
X		}
X	}
X	vttidy(FALSE);
X	if (signo > 2) abort();
X	exit(wrote);
}
#endif
X
markWFMODE(bp)
BUFFER *bp;
{
X	register WINDOW *wp;	/* scan for windows that need updating */
X        wp = wheadp;                    /* Update mode lines.   */
X        while (wp != NULL) {
X                if (wp->w_bufp == bp)
X                        wp->w_flag |= WFMODE;
X                wp = wp->w_wndp;
X        }
}
X
/* use the shell to expand wildcards */
/*  should optimize this to only call shell if wildcards are suspected */
glob(buf)
char *buf;
{
#if UNIX
X	char *cp;
X	char cmd[NFILEN+50];
X	FILE *cf;
X	FILE *npopen();
X
X	/* trim trailing whitespace */
X	cp = &buf[strlen(buf)-1];
X	while (cp != buf) {
X		if (isspace(*cp))
X			*cp = '\0';
X		else
X			break;
X		cp--;
X	}
X
X	cp = buf;
X	if (*cp == '!' || *cp == '[')	/* it's a shell command, or an */
X		return TRUE;		/* internal name, don't bother */
X
X	while (*cp) {
X		if (iswild(*cp)) {
X			sprintf(cmd, "echo %s", buf);
X			cf = npopen(cmd,"r");
X			if (cf == NULL) {
X				return TRUE;
X			}
X			if (fread(buf,1,NFILEN,cf) <= 0) {
X				npclose(cf);
X				return FALSE;
X			}
X			npclose(cf);
X			cp = buf;
X			while (*cp) {
X				if (*cp == ' ' ) {
X					if (mlyesno(
X					"Too many filenames.  Use first"
X							) == TRUE) {
X						*cp = '\0';
X						break;
X					} else {
X						buf[0] = 0;
X						return FALSE;
X					}
X				} else if (*cp == '\n') {
X					*cp = '\0';
X					break;
X				}
X				cp++;
X			}
X			return TRUE;
X
X		}
X		cp++;
X	}
X	return TRUE;
#endif
}
X
#if	CRYPT
resetkey(bp)	/* reset the encryption key if needed */
BUFFER *bp;
{
X	register int s;	/* return status */
X
X	/* turn off the encryption flag */
X	cryptflag = FALSE;
X
X	/* if we are in crypt mode */
X	if (bp->b_mode & MDCRYPT) {
X		if (bp->b_key[0] == 0) {
X			s = setkey(FALSE, 0);
X			if (s != TRUE)
X				return s;
X		}
X
X		/* let others know... */
X		cryptflag = TRUE;
X
X		/* and set up the key to be used! */
X		/* de-encrypt it */
X		crypt((char *)NULL, 0);
X		crypt(bp->b_key, strlen(bp->b_key));
X
X		/* re-encrypt it...seeding it to start */
X		crypt((char *)NULL, 0);
X		crypt(bp->b_key, strlen(bp->b_key));
X	}
X
X	return TRUE;
}
#endif
X
SHAR_EOF
echo 'File file.c is complete' &&
chmod 0444 file.c ||
echo 'restore of file.c failed'
Wc_c="`wc -c < 'file.c'`"
test 28527 -eq "$Wc_c" ||
	echo 'file.c: original size 28527, current size' "$Wc_c"
# ============= fileio.c ==============
echo 'x - extracting fileio.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'fileio.c' &&
/*
X * The routines in this file read and write ASCII files from the disk. All of
X * the knowledge about files are here.
X */
X
#include        <stdio.h>
#include	"estruct.h"
#include        "edef.h"
#if UNIX
#include        <errno.h>
#include        <fcntl.h>
#endif
#if	BSD
#include "sys/filio.h"
#endif
X
/* possibly non-portable addition to stdio set of macros */
#define	isready_c(p)	((p)->_cnt>0? TRUE:FALSE)
X
FILE	*ffp;		/* File pointer, all functions. */
int fileispipe;
int eofflag;		/* end-of-file flag */
#if DOSFILES
int doslines, unixlines;
int dosfile;
#endif
X
X
/*
X * Open a file for reading.
X */
ffropen(fn)
char    *fn;
{
#if UNIX
X	FILE *npopen();
#endif
X
#if DOSFILES
X	doslines = unixlines = 0;
#endif
X
#if UNIX
X	
X	if (*fn == '!') {
X	        if ((ffp=npopen(fn+1, "r")) == NULL)
X	                return (FIOERR);
X		fileispipe = TRUE;
X	} else {
X	        if ((ffp=fopen(fn, "r")) == NULL) {
X			if (errno == ENOENT)
X		                return (FIOFNF);
X	                return (FIOERR);
X		}
X		fileispipe = FALSE;
X	}
#else
X        if ((ffp=fopen(fn, "r")) == NULL)
X                return (FIOFNF);
#endif
X	eofflag = FALSE;
X        return (FIOSUC);
}
X
/*
X * Open a file for writing. Return TRUE if all is well, and FALSE on error
X * (cannot create).
X */
ffwopen(fn)
char    *fn;
{
#if UNIX
X	if (*fn == '!') {
X	        if ((ffp=npopen(fn+1, "w")) == NULL) {
X	                mlwrite("Cannot open pipe for writing");
X			TTbeep();
X	                return (FIOERR);
X		}
X		fileispipe = TRUE;
X	} else {
X	        if ((ffp=fopen(fn, "w")) == NULL) {
X	                mlwrite("Cannot open file for writing");
X			TTbeep();
X	                return (FIOERR);
X		}
X		fileispipe = FALSE;
X	}
#else
#if     VMS
X        register int    fd;
X
X        if ((fd=creat(fn, 0666, "rfm=var", "rat=cr")) < 0
X        || (ffp=fdopen(fd, "w")) == NULL) {
X                mlwrite("Cannot open file for writing");
X                return (FIOERR);
X        }
#else
X        if ((ffp=fopen(fn, "w")) == NULL) {
X                mlwrite("Cannot open file for writing");
X                return (FIOERR);
X        }
#endif
#endif
X        return (FIOSUC);
}
X
/* is the file read-only?  true or false */
#if UNIX  /* don't know how to do it for other systems */
ffronly(fn)
char    *fn;
{
X	int fd;
X
X	if (*fn == '!') {
X		return TRUE;
X	} else {
X	        if ((fd=open(fn, O_WRONLY)) < 0) {
X	                return TRUE;
X		}
X		close(fd);
X		return FALSE;
X	}
}
#endif
X
/*
X * Close a file. Should look at the status in all systems.
X */
ffclose()
{
X	int s;
X
X	/* free this since we do not need it anymore */
X	if (fline) {
X		free(fline);
X		fline = NULL;
X		flen = 0;
X	}
X
#if	MSDOS & CTRLZ & NEVER
X	 but we NEVER want to do this on read closes!!!
X	fputc(26, ffp);		/* add a ^Z at the end of the file */
#endif
X	
#if DOSFILES
X	/* did we get more dos-style lines than unix-style? */
X	dosfile = (doslines > unixlines);
X	unixlines = 0;
#endif
#if UNIX | (MSDOS & (LATTICE | MSC | TURBO))
#if UNIX
X	
X	if (fileispipe)
X		s = npclose(ffp);
X	else
#endif
X		s = fclose(ffp);
X        if (s != 0) {
X                mlwrite("Error on close");
X                return(FIOERR);
X        }
X        return(FIOSUC);
#else
X        fclose(ffp);
X        return (FIOSUC);
#endif
}
X
/*
X * Write a line to the already opened file. The "buf" points to the buffer,
X * and the "nbuf" is its length, less the free newline. Return the status.
X * Check only at the newline.
X */
ffputline(buf, nbuf)
char    buf[];
{
X        register int    i;
#if	CRYPT
X	char c;		/* character to translate */
X
X	if (cryptflag) {
X	        for (i = 0; i < nbuf; ++i) {
X			c = buf[i] & 0xff;
X			crypt(&c, 1);
X			fputc(c, ffp);
X		}
X	} else
X	        for (i = 0; i < nbuf; ++i)
X        	        fputc(buf[i]&0xFF, ffp);
#else
X        for (i = 0; i < nbuf; ++i)
X                fputc(buf[i]&0xFF, ffp);
#endif
X
#if	ST520
X        fputc('\r', ffp);
#endif        
#if DOSFILES
X	if (dosfile) {
X		/* put out CR, unless we just did */
X		if (i == 0 || buf[i-1] != '\r')
X		        fputc('\r', ffp);
X	}
#endif
X        fputc('\n', ffp);
X
X        if (ferror(ffp)) {
X                mlwrite("Write I/O error");
X                return (FIOERR);
X        }
X
X        return (FIOSUC);
}
/*
X * Write a charto the already opened file.
X * Return the status.
X */
ffputc(c)
{
X	static lastc;
X	c &= 0xff;
#if DOSFILES
X	if (dosfile && c == '\n' && lastc != '\r')
X		 fputc('\r',ffp);
#endif
X	lastc = c;
X
#if	CRYPT
X	if (cryptflag)
X		crypt(&c, 1);
#endif
X        fputc(c, ffp);
X
X        if (ferror(ffp)) {
X                mlwrite("Write I/O error");
X                return (FIOERR);
X        }
X
X        return (FIOSUC);
}
X
/*
X * Read a line from a file, and store the bytes in an allocated buffer.
X * "flen" is the length of the buffer. Reallocate and copy as necessary.
X * Check for I/O errors. Return status.
X */
ffgetline(lenp)
int *lenp;	/* to return the final length */
{
X        register int c;		/* current character read */
X        register int i;		/* current index into fline */
X	register char *tmpline;	/* temp storage for expanding line */
X
X	/* if we are at the end...return it */
X	if (eofflag)
X		return(FIOEOF);
X
#if BEFORE	/* no no no -- malloc is expensive... */
X	/* dump fline if it ended up too big */
X	if (flen > NSTRING) {
X		free(fline);
X		fline = NULL;
X		flen = 0;
X	}
#endif
X
X	/* if we don't have an fline, allocate one */
X	if (fline == NULL)
X		if ((fline = malloc(flen = NSTRING)) == NULL)
X			return(FIOMEM);
X
X	/* read the line in */
X        i = 0;
X        while ((c = fgetc(ffp)) != EOF && c != '\n') {
X                fline[i++] = c;
X		/* if it's longer, get more room */
X                if (i >= flen) {
X                	if ((tmpline = malloc(flen+NSTRING)) == NULL)
X                		return(FIOMEM);
X                	strncpy(tmpline, fline, flen);
X                	flen += NSTRING;
X                	free(fline);
X                	fline = tmpline;
X                }
X        }
X
#if !DOSFILES
#if	ST520
X	if(fline[i-1] == '\r') {
X		i--;
X	}
#endif
#else
X	if(fline[i-1] == '\r') {
X		doslines++;
X		i--;
X	} else {
X		unixlines++;
X	}
#endif
X
X	*lenp = i;	/* return the length, not including final null */
X        fline[i] = 0;
#if TESTING
if (i > 0) {
X	if (isready_c(ffp))
X		fline[0] = 'y';
X	else
X		fline[0] = 'n';
X	if (i > 1) {
X		long x;
X		if ((ioctl(fileno(ffp),FIONREAD,&x) < 0) || x == 0)
X			fline[1] = 'n';
X		else
X			fline[1] = 'y';
X	}	
}	
#endif
X	/* test for any errors that may have occured */
X        if (c == EOF) {
X                if (ferror(ffp)) {
X                        mlwrite("File read error");
X                        return(FIOERR);
X                }
X
X                if (i != 0)
X			eofflag = TRUE;
X		else
X			return(FIOEOF);
X        }
X
#if	CRYPT
X	/* decrypt the string */
X	if (cryptflag)
X		crypt(fline, strlen(fline));
#endif
X        return(FIOSUC);
}
X
ffhasdata()
{
X	long x;
#if	BSD
X	if (isready_c(ffp))
X		return TRUE;
X	return(((ioctl(fileno(ffp),FIONREAD,&x) < 0) || x == 0) ? FALSE : TRUE);
#else
X	return FALSE;
#endif
}
X
#if	AZTEC & MSDOS
#undef	fgetc
/*	a1getc:		Get an ascii char from the file input stream
X			but DO NOT strip the high bit
*/
X
int a1getc(fp)
X
FILE *fp;
X
{
X	int c;		/* translated character */
X
X	c = getc(fp);	/* get the character */
X
X	/* if its a <LF> char, throw it out  */
X	while (c == '\n')
X		c = getc(fp);
X
X	/* if its a <RETURN> char, change it to a LF */
X	if (c == '\r')
X		c = '\n';
X
X	/* if its a ^Z, its an EOF */
X	if (c == 26)
X		c = EOF;
X
X	return(c);
}
#endif
SHAR_EOF
chmod 0444 fileio.c ||
echo 'restore of fileio.c failed'
Wc_c="`wc -c < 'fileio.c'`"
test 7384 -eq "$Wc_c" ||
	echo 'fileio.c: original size 7384, current size' "$Wc_c"
# ============= finderr.c ==============
echo 'x - extracting finderr.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'finderr.c' &&
/* written for vile by Paul Fox, (c)1990 */
X
#include	"estruct.h"
#include        "edef.h"
X
#if FINDERR
X
#ifndef NULL
#define NULL 0
#endif
X
struct LINE *getdot();
X
/* edits the file and goes to the line pointed at by the next compiler
X        error in the "[output]" window.  It unfortunately doesn't mark
X        the lines for you, so adding lines to the file throws off the
X        later numbering.  Solutions to this seem messy at the moment */
X
finderr(f,n)
{
X	register BUFFER *sbp;
X	register LINE *lp;
X	register int i = 0;
X	register int s = TRUE;
X	struct LINE *dotp;
X	int moveddot = FALSE;
X	
X	int errline;
X	char errfile[NFILEN];
X	
X	static int oerrline = -1;
X	static char oerrfile[NFILEN];
X
X	/* look up the right buffer */
X        if ((sbp=bfind(febuff, NO_CREAT, 0)) == NULL) {
X        	mlwrite("No buffer to search for errors.");
X                return(FALSE);
X        }
X        
X        if (newfebuff) {
X        	oerrline = -1;
X        	oerrfile[0] = '\0';
X        }
X        newfebuff = FALSE;
X
X	dotp = getdot(sbp);
X
X	for(;;) {
X		/* to use this line, we need both the filename and the line
X			number in the expected places, and a different line
X			than last time */
X		/* accept lines of the form:
X			"file.c", line 223: error....
X			or
X			file.c: 223: error....
X		*/
X		if ((sscanf(dotp->l_text,
X			"\"%[^\" 	]\", line %d:",errfile,&errline) == 2 ||
X		     sscanf(dotp->l_text,
X			"%[^: 	]: %d:",errfile,&errline) == 2 
X			) &&
X			(oerrline != errline || strcmp(errfile,oerrfile))) {
X				break;
X		}
X			
X		if (lforw(dotp) == sbp->b_linep) {
X			mlwrite("No more errors in %s buffer", febuff);
X			TTbeep();
X			/* start over at the top of file */
X			putdotback(sbp, lforw(sbp->b_linep));
X			return FALSE;
X		}
X		dotp = lforw(dotp);
X		moveddot = TRUE;
X	}
X	/* put the new dot back, before possible changes to contents
X				of current window from getfile() */
X	if (moveddot)
X		putdotback(sbp,dotp);
X
X	if (strcmp(errfile,curbp->b_fname)) { /* if we must change windows */
X		struct WINDOW *wp;
X		wp = wheadp;
X		while (wp != NULL) {
X			if (!strcmp(wp->w_bufp->b_fname,errfile))
X				break;
X			wp = wp->w_wndp;
X		}
X		if (wp) {
X			curwp = wp;
X			make_current(curwp->w_bufp);
X			upmode();
X		} else {
X			s = getfile(errfile,TRUE);
X			if (s != TRUE)
X				return s;
X		}
X	}
X
X	mlwrite("Error is %S", dotp->l_used, dotp->l_text);
X
X	/* it's an absolute move */
X	curwp->w_ldmkp = curwp->w_dotp;
X	curwp->w_ldmko = curwp->w_doto;
X	gotoline(TRUE,errline);
X
X	oerrline = errline;
X	strcpy(oerrfile,errfile);
X
X	return TRUE;
X
}
X
struct LINE *
getdot(bp)
struct BUFFER *bp;
{
X	register WINDOW *wp;
X	if (bp->b_nwnd) {
X		/* scan for windows holding that buffer, 
X					pull dot from the first */
X	        wp = wheadp;
X	        while (wp != NULL) {
X	                if (wp->w_bufp == bp) {
X	                        return wp->w_dotp;
X			}
X	                wp = wp->w_wndp;
X	        }
X	}
X        return bp->b_dotp;
}
X
putdotback(bp,dotp)
struct BUFFER *bp;
struct LINE *dotp;
{
X	register WINDOW *wp;
X
X	if (bp->b_nwnd) {
X	        wp = wheadp;
X	        while (wp != NULL) {
X	                if (wp->w_bufp == bp) {
X		                wp->w_dotp = dotp;
X		                wp->w_doto = 0;
X			        wp->w_flag |= WFMOVE;
X			}
X	                wp = wp->w_wndp;
X	        }
X		return;
X	}
X	/* then the buffer isn't displayed */
X        bp->b_dotp = dotp;
X        bp->b_doto = 0;
}
X
#else
finderrhello() { }
#endif
SHAR_EOF
chmod 0444 finderr.c ||
echo 'restore of finderr.c failed'
Wc_c="`wc -c < 'finderr.c'`"
test 3373 -eq "$Wc_c" ||
	echo 'finderr.c: original size 3373, current size' "$Wc_c"
# ============= globals.c ==============
echo 'x - extracting globals.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'globals.c' &&
#include	"estruct.h"
#include        "edef.h"
#include        <stdio.h>
X
/* ed/vi/ex style global commands, where first the file is scanned for
X	matching lines, then for each such line, an action is performed.
X	written for vile by Paul Fox, (c)1990
*/
#if GLOBALS
X
globals(f,n)
{
X	return globber(f,n,'g');
}
X
vglobals(f,n)
{
#ifdef SOMEDAY
X	return globber(f,n,'v');
#else
X	return unimpl();
#endif
}
X
globber(f, n, g_or_v)
{
X	static char buf[NFILEN];
X	int c, s;
X	register LINE *lp;
X	register char *fnp;	/* ptr to the name of the cmd to exec */
X	char *kbd_engl();
X	CMDFUNC *engl2fnc();
X	CMDFUNC *cfp;
X	int foundone;
X	extern CMDFUNC f_godotplus;
X	
X	c = '\n';
X	if (isnamedcmd) {
X		c = tpeekc();
X		if (c < 0) {
X			c = '\n';
X		} else {
X			if (ispunct(c)) {
X				(void)kbd_key();
X			}
X		}
X	}
X	if (readpattern("global pattern: ", &pat[0], TRUE, c, FALSE) != TRUE) {
X		mlwrite("No pattern.");
X		return FALSE;
X	}
X
X	/* in some sense, it would be nice to search first, before
X                making the user answer the next question, but the
X                searching delay is too long, and unexpected in the
X                middle of a command.  */
X
X	mlwrite("action to perform on each matching line: ");
X	/* and now get the name of, and then the function to execute */
X	cfp = NULL;
X	fnp = kbd_engl();
X	if (!fnp || !fnp[0]) {
X	        mlwrite("[No function]");
X		return FALSE;
X	} else if (!(cfp = engl2fnc(fnp))) {
X	        mlwrite("[No such function]");
X		return FALSE;
X	} else if ((cfp->c_flags & GLOBOK) == 0) {
X	        mlwrite("[Function not allowed]");
X		return FALSE;
X	}
X	
X	
X	/* call the searcher, telling it to do line marking */
X	s = fsearch(FALSE,0,TRUE,NULL);
X	if (s != TRUE)
X		return s;
X	
X	calledbefore = FALSE;
X	
X	/* loop through the buffer -- we must clear the marks no matter what */
X	s = TRUE;
X	lp = lforw(curbp->b_linep);
X	/* loop until there are no marked lines in the buffer */
X	foundone = FALSE;
X	for(;;) {
X		if (lp == curbp->b_linep) {
X			/* at the end -- only quit if we found no 
X				marks on the last pass through. otherwise,
X				go through again */
X			if (foundone)
X				foundone = FALSE;
X			else
X				break;
X		}
X		if (lismarked(lp)) {
X			foundone = TRUE;
X			lsetnotmarked(lp);
X			curwp->w_dotp = lp;
X			curwp->w_doto = 0;
X			/* call the function, if there is one, and results
X				have been ok so far */
X			if (cfp && s) {
X				if (!calledbefore && (cfp->c_flags & UNDO)) {
X					if (curbp->b_mode&MDVIEW)
X						return(rdonly());
X					mayneedundo();
X				}
X				havemotion = &f_godotplus;
X				s = (cfp->c_func)(FALSE, 1, NULL, NULL);
X				havemotion = NULL;
X				calledbefore = TRUE;
X			}
X			if (lp != curwp->w_dotp) {
X				/* make sure we're still in the buffer, since
X					action might have caused delete, etc. */
X				lp = curwp->w_dotp;
X			}
X		}
X		lp = lforw(lp);
X	}
X
X	cfp = NULL;
X
X	return s;
}
X
#else
globalhello() { }
#endif
SHAR_EOF
chmod 0444 globals.c ||
echo 'restore of globals.c failed'
Wc_c="`wc -c < 'globals.c'`"
test 2834 -eq "$Wc_c" ||
	echo 'globals.c: original size 2834, current size' "$Wc_c"
# ============= hp110.c ==============
echo 'x - extracting hp110.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hp110.c' &&
/*
X *	HP110:	Hewlett Packard 110 Screen Driver
X */
X
#define	termdef	1			/* don't define "term" external */
X
#include        <stdio.h>
#include	"estruct.h"
#include        "edef.h"
X
#if     HP110
X
#define NROW    16                      /* Screen size.                 */
#define NCOL    80                      /* Edit if you want to.         */
#define	NPAUSE	100			/* # times thru update to pause */
#define	MARGIN	8			/* size of minimim margin and	*/
#define	SCRSIZ	64			/* scroll size for extended lines */
#define BEL     0x07                    /* BEL character.               */
#define ESC     0x1B                    /* ESC character.               */
X
extern  int     ttopen();               /* Forward references.          */
extern  int     ttgetc();
extern  int     ttputc();
extern  int     ttflush();
extern  int     ttclose();
extern  int     h110move();
extern  int     h110eeol();
extern  int     h110eeop();
extern  int     h110beep();
extern  int     h110open();
extern	int	h110rev();
extern	int	h110cres();
extern	int	h110close();
extern	int	h110kopen();
extern	int	h110kclose();
X
#if	COLOR
extern	int	h110fcol();
extern	int	h110bcol();
X
int	cfcolor = -1;		/* current forground color */
int	cbcolor = -1;		/* current background color */
#endif
X
/*
X * Standard terminal interface dispatch table. Most of the fields point into
X * "termio" code.
X */
TERM    term    = {
X	NROW-1,
X        NROW-1,
X        NCOL,
X        NCOL,
X	MARGIN,
X	SCRSIZ,
X	NPAUSE,
X        h110open,
X        h110close,
X	h110kopen,
X	h110kclose,
X        ttgetc,
X        ttputc,
X        ttflush,
X        h110move,
X        h110eeol,
X        h110eeop,
X        h110beep,
X	h110rev,
X	h110cres
#if	COLOR
X	, h110fcol,
X	h110bcol
#endif
};
X
#if	COLOR
h110fcol(color)		/* set the current output color */
X
int color;	/* color to set */
X
{
X	if (color == cfcolor)
X		return;
X	ttputc(ESC);
X	ttputc('[');
X	h110parm(color+30);
X	ttputc('m');
X	cfcolor = color;
}
X
h110bcol(color)		/* set the current background color */
X
int color;	/* color to set */
X
{
X	if (color == cbcolor)
X		return;
X	ttputc(ESC);
X	ttputc('[');
X	h110parm(color+40);
X	ttputc('m');
X        cbcolor = color;
}
#endif
X
h110move(row, col)
{
X        ttputc(ESC);
X        ttputc('[');
X        h110parm(row+1);
X        ttputc(';');
X        h110parm(col+1);
X        ttputc('H');
}
X
h110eeol()
{
X        ttputc(ESC);
X        ttputc('[');
X	ttputc('0');
X        ttputc('K');
}
X
h110eeop()
{
#if	COLOR
X	h110fcol(gfcolor);
X	h110bcol(gbcolor);
#endif
X        ttputc(ESC);
X        ttputc('[');
X	ttputc('0');
X        ttputc('J');
}
X
h110rev(state)		/* change reverse video state */
X
int state;	/* TRUE = reverse, FALSE = normal */
X
{
#if	COLOR
X	int ftmp, btmp;		/* temporaries for colors */
#endif
X
X	ttputc(ESC);
X	ttputc('[');
X	ttputc(state ? '7': '0');
X	ttputc('m');
#if	COLOR
X	if (state == FALSE) {
X		ftmp = cfcolor;
X		btmp = cbcolor;
X		cfcolor = -1;
X		cbcolor = -1;
X		h110fcol(ftmp);
X		h110bcol(btmp);
X	}
#endif
}
X
h110cres()	/* change screen resolution */
X
{
X	return(TRUE);
}
X
spal()		/* change pallette register */
X
{
X	/*   not here */
}
X
h110beep()
{
X        ttputc(BEL);
X        ttflush();
}
X
h110parm(n)
register int    n;
{
X        register int q,r;
X
X        q = n/10;
X        if (q != 0) {
X		r = q/10;
X		if (r != 0) {
X			ttputc((r%10)+'0');
X		}
X		ttputc((q%10) + '0');
X        }
X        ttputc((n%10) + '0');
}
X
h110open()
{
X	strcpy(sres, "15LINE");
X	revexist = TRUE;
X        ttopen();
}
X
h110close()
X
{
#if	COLOR
X	h110fcol(7);
X	h110bcol(0);
#endif
X	ttclose();
}
X
h110kopen()
X
{
}
X
h110kclose()
X
{
}
X
#if	FLABEL
fnclabel(f, n)		/* label a function key */
X
int f,n;	/* default flag, numeric argument [unused] */
X
{
X	/* on machines with no function keys...don't bother */
X	return(TRUE);
}
#endif
#else
h110hello()
{
}
#endif
SHAR_EOF
chmod 0444 hp110.c ||
echo 'restore of hp110.c failed'
Wc_c="`wc -c < 'hp110.c'`"
test 3750 -eq "$Wc_c" ||
	echo 'hp110.c: original size 3750, current size' "$Wc_c"
# ============= hp150.c ==============
echo 'x - extracting hp150.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hp150.c' &&
/*
X * The routines in this file provide support for HP150 screens
X * and routines to access the Keyboard through KEYCODE mode.
X * It compiles into nothing if not an HP150 screen device.
X * added by Daniel Lawrence
X */
X
#define	termdef	1			/* don't define "term" external */
X
#include        <stdio.h>
#include        "estruct.h"
#include	"edef.h"
X
#if     HP150
X
#define NROW    24                      /* Screen size.                 */
#define NCOL    80                      /* Edit if you want to.         */
#define	MARGIN	8			/* size of minimim margin and	*/
#define	SCRSIZ	64			/* scroll size for extended lines */
#define	NPAUSE	15			/* # times thru update to pause */
#define BEL     0x07                    /* BEL character.               */
#define ESC     0x1B                    /* ESC character.               */
X
extern  int     openhp();               /* Forward references.          */
extern  int     ttgetc();
extern  int     ttputc();
extern  int     ttflush();
extern	int	hpflush();
extern  int     closehp();
extern	int	hp15kopen();
extern	int	hp15kclose();
extern  int     hp15move();
extern  int     hp15eeol();
extern  int     hp15eeop();
extern  int     hp15beep();
extern	int	gethpkey();
extern	int	hp15rev();
extern	int	hp15cres();
#if	COLOR
extern	int	hp15fcol();
extern	int	hp15bcol();
#endif
X
/* weird to ascii translation table */
X
char trans[][2] = {
X	0x24,	9,	/* tab */
X	0x25,	13,	/* ret */
X	0x27,	8,	/* backspace */
X	0x30,	48,	/* zero */
X	0x31,	49,	/* one */
X	0x32,	50,	/* two */
X	0x33,	51,	/* three */
X	0x34,	52,	/* four */
X	0x35,	53,	/* five */
X	0x36,	54,	/* six */
X	0x37,	55,	/* seven */
X	0x38,	56,	/* eight */
X	0x39,	57,	/* nine */
X	0x50,	13,	/* enter */
X	0x54,	27,	/* break -> ESC */
X	0x55,	27,	/* esc */
X	0x58,	24,	/* stop -> ^X */
X	0x70,	45,	/* N-minus */
X	0x71,	42,	/* N-asterisk */
X	0x72,	43,	/* N-plus */
X	0x73,	47,	/* N-slash */
X	0x74,	44,	/* N-comma */
X	0x75,	13,	/* N-enter */
X	0x76,	9,	/* N-tab */
X	0x77,	46	/* N-period */
};
X
#define NTRANS	sizeof(trans) / 2
X
union REGS r;		/* register set for bios and dos (AGIOS) calls */
int capslock = 0;	/* caps lock flag */
X
/*
X * Standard terminal interface dispatch table. Most of the fields point into
X * "termio" code.
X */
TERM    term    = {
X	NROW-1,
X        NROW-1,
X        NCOL,
X        NCOL,
X	MARGIN,
X	SCRSIZ,
X	NPAUSE,
X	openhp,
X        closehp,
X	hp15kopen,
X	hp15kclose,
X	gethpkey,
X        ttputc,
X        hpflush,
X        hp15move,
X        hp15eeol,
X        hp15eeop,
X        hp15beep,
X        hp15rev,
X        hp15cres
#if	COLOR
X	, hp15fcol,
X	hp15bcol
#endif
};
X
hp15move(row, col)
{
X        ttputc(ESC);
X        ttputc('&');
X        ttputc('a');
X        hp15parm(col);
X        ttputc('c');
X        hp15parm(row);
X        ttputc('R');
}
X
hpflush()
X
{
X
}
X
hp15eeol()
{
X        ttputc(ESC);
X        ttputc('K');
}
X
hp15eeop()
{
X        ttputc(ESC);
X        ttputc('J');
}
X
hp15rev(status)		/* change the reverse video status */
X
int status;	/* TRUE = on, FALSE = off */
X
{
X	ttputc(ESC);
X	ttputc('&');
X	ttputc('d');
X	ttputc((status != FALSE) ? 'B': '@');
}
X
hp15cres()	/* change screen resolution */
X
{
X	return(TRUE);
}
X
spal()		/* change pallette register */
X
{
X	/*   not here */
}
X
hp15beep()
{
X        ttputc(BEL);
X        ttflush();
}
X
hp15parm(n)
register int    n;
{
X        register int    q;
X
X        q = n/10;
X        if (q != 0)
X                hp15parm(q);
X        ttputc((n%10) + '0');
}
X
#if	COLOR
hp15fcol()	/* we really can't do colors here, so just ignore it */
{
}
X
hp15bcol()	/* we really can't do colors here, so just ignore it */
{
}
#endif
X
gethpkey()	/* get a key from the HP keyboard while in keycode mode */
X
{
X	static int keepflag = 0;	/* kept ahead char flag */
X	static int keepchar = 0;	/* kept ehead flag */
X	int c;
X	int devid;			/* device ID */
X	int ctype;			/* type of character gotten */
X	int shiftb;			/* state of shift keys */
X	int i;
X	
X	/* if we are in an extended char sequence, finish it */
X	if (keepflag != 0) {
X		keepflag = 0;
X		return(keepchar);
X	}
X
X	/* grab the next 4 char sequence */
next:	shiftb = ttgetc();
X	devid = ttgetc();
X	c = ttgetc();
X	ttgetc();		/* skip null byte */
X	
X	/* make sure we are from the keyboard */
X	if (devid != 192)
X		goto next;
X
X	/* if normal ascii, return it */
X	if ((shiftb & 0x80) == 0) {
X		if (capslock && c >= 'a' && c <= 'z')
X			c -= 32;
X		return(c);
X	}
X
X	/* check specifically for the caps lock key */
X	if (c == 0x56) {
X		capslock = ~capslock;
X		goto next;
X	}
X
X	/* check to see if it needs translation */
X	for (i=0; i < NTRANS; i++)
X		if (trans[i][0] == c)
X			return((int)trans[i][1]);
X
X	/* other wise, shove it in the keep char and return the leadin code */
X	keepchar = c;
X	keepflag = 1;
X	return(0);
}
X
openhp()		/* open the HP150 screen for input */
X
{
X	strcpy(sres, "NORMAL");
X	revexist = TRUE;
}
X
closehp()		/* close the HP150 screen for input */
X
{
}
X
hp15kopen()		/* open the HP150 keyboard for input */
X
{
X	/* define key charectoristics with AGIOS call (0, 40) */
X	defkey();
X
X	/* Turn on RAW mode with MSDOS call 44h */
X	rawon();
X
X	/* Turn off Control-C checking  MS-DOS 33h */
X	ckeyoff();
X
X	/* Turn on keycode mode with AGIOS call (0,43) */
X	keycon();
X
X	/* display the application softkey labels */
X	dsplbls();
}
X
hp15kclose()		/* close the HP150 keyboard for input */
X
{
X	/* define key charectoristics with AGIOS call (0, 40) */
X	undefkey();
X	
X	/* Turn off RAW mode with MSDOS call 44h */
X	rawoff();
X
X	/* Turn on Control-C checking  MS-DOS 33h */
X	ckeyon();
X
X	/* Turn off keycode mode with AGIOS call (0,43) */
X	keycoff();
}
X
rawon()		/* put the HP150 keyboard into RAW mode */
X
{
X	/* get the IO control info */
X
X	r.x.ax = 0x4400;	/* IO ctrl get device information */
X	r.x.bx = 0x0001;	/* File handle; 1 for console */
X	intdos(&r, &r);		/* go fer it */
X
X	r.h.dh = 0;		/* clear high byte for put */
X	r.h.dl |= 0x20;		/* set raw bit */
X
X	/* and put it back */
X
X	r.x.ax = 0x4401;	/* IO ctrl put device information */
X	r.x.bx = 0x0001;	/* File handle; 1 for console */
X	intdos(&r, &r);		/* go fer it */
}
X
rawoff()	/* put the HP150 keyboard into COOKED mode */
X
{
X	/* get the IO control info */
X
X	r.x.ax = 0x4400;	/* IO ctrl get device information */
X	r.x.bx = 0x0001;	/* File handle; 1 for console */
X	intdos(&r, &r);		/* go fer it */
X
X	r.h.dh = 0;		/* clear high byte for put */
X	r.h.dl &= 0xdf;		/* set raw bit */
X
X	/* and put it back */
X
X	r.x.ax = 0x4401;	/* IO ctrl put device information */
X	r.x.bx = 0x0001;	/* File handle; 1 for console */
X	intdos(&r, &r);		/* go fer it */
}
X
X
ckeyoff()	/* turn control-C trapping off */
X
{
X	r.h.ah = 0x33;	/* ctrl-break check */
X	r.h.al = 1;	/* set the state of the ctrl-break check */
X	r.h.dl = 0;	/* turn it off */
X	intdos(&r, &r);
}
X
ckeyon()	/* turn control-C trapping on */
X
{
X	r.h.ah = 0x33;	/* ctrl-break check */
X	r.h.al = 1;	/* set the state of the ctrl-break check */
X	r.h.dl = 1;	/* turn it on */
X	intdos(&r, &r);
}
X
#ifdef	unsigned
#undef	unsigned
#endif
X
agios(buf, len)	/* perform an AGIOS call */
X
char *buf;	/* sequence of bytes in command */
int len;	/* length of command in bytes */
X
{
X	r.x.ax = 0x4403;	/* I/O ctrl write */
X	r.x.bx = 1;		/* console handle */
X	r.x.cx = len;		/* buffer length */
X	r.x.dx = (unsigned)buf;	/* buffer address */
X	return(intdos(&r, &r));	/* do it */
}
X
keycon()	/* turn keycode mode on */
X
{
X	static char cmd[] = {43, 0, 1};
X
X	return(agios(&cmd[0], 3));
}
X
keycoff()	/* turn keycode mode off */
X
{
X	static char cmd[] = {43, 0, 0};
X
X	return(agios(&cmd[0], 3));
}
X
defkey()	/* change all special keys to intercept mode */
X
{
X	static char cmd[] = {40, 0, 2, 0, 0xfe, 0};
X
X	return(agios(&cmd[0], 6));
}
X
undefkey()	/* change all special keys to intercept mode */
X
{
X	static char cmd[] = {40, 0, 0, 0, 0xfe, 0};
X
X	return(agios(&cmd[0], 6));
}
X
dsplbls()	/* display the application softkey labels on the screen */
X
{
X	static char cmd[] = {11, 0};
X
X	return(agios(&cmd[0], 2));
}
X
#if	FLABEL
fnclabel(f, n)		/* label a function key */
X
int f,n;	/* default flag, numeric argument */
X
{
X	register int status;	/* return status */
X	register int i;		/* loop index */
X	char lbl[17];	/* returned label contents */
X	/* AGIOS command buffer */
X	static char cmd[] = {8, 0, 1, 0, 7, 7, 7, 7, 10, 0, 10, 0};
X	/*                   code  key#  ptr to      top    bottom
X	                                 label string  attribute */
X	union {		/* union to cast ptr into AGIOS arg string */
X		char *ptr;	/* pointer to arg string */
X		char cstr[4];
X	} ptru;
X
X	/* must have a numeric argument */
X	if (f == FALSE) {
X		mlwrite("%Need function key number");
X		return(FALSE);
X	}
X
X	/* and it must be a legal key number */
X	if (n < 1 || n > 8) {
X		mlwrite("%Function key number out of range");
X		return(FALSE);
X	}
X
X	/* get the string to send */
X	lbl[0] = 0;
X	status = mlreply("Label contents: ", &lbl[0], 17);
X	if (status != TRUE)
X		return(status);
X
X	/* pad the label out */
X	for (i=0; i < 17; i++) {
X		if (lbl[i] == 0)
X			break;
X	}
X	for (; i < 16; i++)
X		lbl[i] = ' ';
X	lbl[16] = 0;
X
X	/* set up the parameters */
X	cmd[2] = n;			/* function key number */
X	ptru.ptr = &lbl[0];		/* set up pointer to label string */
force:	cmd[4] = ptru.cstr[0];
X	cmd[5] = ptru.cstr[1];
X	cmd[6] = ptru.cstr[2];
X	cmd[7] = ptru.cstr[3];
X
X	/* and send it out */
X	agios(&cmd[0], 12);
X	return(TRUE);
}
#endif
#else
X
h15hello()
X
{
}
#endif
SHAR_EOF
chmod 0444 hp150.c ||
echo 'restore of hp150.c failed'
Wc_c="`wc -c < 'hp150.c'`"
test 9245 -eq "$Wc_c" ||
	echo 'hp150.c: original size 9245, current size' "$Wc_c"
# ============= ibmpc.c ==============
echo 'x - extracting ibmpc.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ibmpc.c' &&
/*
X * The routines in this file provide support for the IBM-PC and other
X * compatible terminals. It goes directly to the graphics RAM to do
X * screen output. It compiles into nothing if not an IBM-PC driver
X * Supported monitor cards include CGA, MONO and EGA.
X */
X
#define	termdef	1			/* don't define "term" external */
X
#include        <stdio.h>
#include	"estruct.h"
#include        "edef.h"
X
#if     IBMPC
#define NROW	43			/* Max Screen size.		*/
#define NCOL    80                      /* Edit if you want to.         */
#define	MARGIN	8			/* size of minimim margin and	*/
#define	SCRSIZ	64			/* scroll size for extended lines */
#define	NPAUSE	200			/* # times thru update to pause */
#define BEL     0x07                    /* BEL character.               */
#define ESC     0x1B                    /* ESC character.               */
#define	SPACE	32			/* space character		*/
X
#define	SCADC	0xb8000000L		/* CGA address of screen RAM	*/
#define	SCADM	0xb0000000L		/* MONO address of screen RAM	*/
#define SCADE	0xb8000000L		/* EGA address of screen RAM	*/
X
#define MONOCRSR 0x0B0D			/* monochrome cursor	    */
#define CGACRSR 0x0607			/* CGA cursor		    */
#define EGACRSR 0x0709			/* EGA cursor		    */
X
#define	CDCGA	0			/* color graphics card		*/
#define	CDMONO	1			/* monochrome text card		*/
#define	CDEGA	2			/* EGA color adapter		*/
#define	CDSENSE	9			/* detect the card type		*/
X
#define NDRIVE	3			/* number of screen drivers	*/
X
int dtype = -1;				/* current display type		*/
char drvname[][8] = {			/* screen resolution names	*/
X	"CGA", "MONO", "EGA"
};
long scadd;				/* address of screen ram	*/
int *scptr[NROW];			/* pointer to screen lines	*/
unsigned int sline[NCOL];		/* screen line image		*/
int egaexist = FALSE;			/* is an EGA card available?	*/
extern union REGS rg;			/* cpu register for use of DOS calls */
X
extern  int     ttopen();               /* Forward references.          */
extern  int     ttgetc();
extern  int     ttputc();
extern  int     ttflush();
extern  int     ttclose();
extern  int     ibmmove();
extern  int     ibmeeol();
extern  int     ibmeeop();
extern  int     ibmbeep();
extern  int     ibmopen();
extern	int	ibmrev();
extern	int	ibmcres();
extern	int	ibmclose();
extern	int	ibmputc();
extern	int	ibmkopen();
extern	int	ibmkclose();
X
#if	COLOR
extern	int	ibmfcol();
extern	int	ibmbcol();
X
int	cfcolor = -1;		/* current forground color */
int	cbcolor = -1;		/* current background color */
int	ctrans[] =		/* ansi to ibm color translation table */
X	{0, 4, 2, 6, 1, 5, 3, 7};
#endif
X
/*
X * Standard terminal interface dispatch table. Most of the fields point into
X * "termio" code.
X */
TERM    term    = {
X	NROW-1,
X        NROW-1,
X        NCOL,
X        NCOL,
X	MARGIN,
X	SCRSIZ,
X	NPAUSE,
X        ibmopen,
X        ibmclose,
X	ibmkopen,
X	ibmkclose,
X        ttgetc,
X	ibmputc,
X        ttflush,
X        ibmmove,
X        ibmeeol,
X        ibmeeop,
X        ibmbeep,
X	ibmrev,
X	ibmcres
#if	COLOR
X	, ibmfcol,
X	ibmbcol
#endif
};
X
#if	COLOR
ibmfcol(color)		/* set the current output color */
X
int color;	/* color to set */
X
{
X	cfcolor = ctrans[color];
}
X
ibmbcol(color)		/* set the current background color */
X
int color;	/* color to set */
X
{
X        cbcolor = ctrans[color];
}
#endif
X
ibmmove(row, col)
{
X	rg.h.ah = 2;		/* set cursor position function code */
X	rg.h.dl = col;
X	rg.h.dh = row;
X	rg.h.bh = 0;		/* set screen page number */
X	int86(0x10, &rg, &rg);
}
X
ibmeeol()	/* erase to the end of the line */
X
{
X	unsigned int attr;	/* attribute byte mask to place in RAM */
X	unsigned int *lnptr;	/* pointer to the destination line */
X	int i;
X	int ccol;	/* current column cursor lives */
X	int crow;	/*	   row	*/
X
X	/* find the current cursor position */
X	rg.h.ah = 3;		/* read cursor position function code */
X	rg.h.bh = 0;		/* current video page */
X	int86(0x10, &rg, &rg);
X	ccol = rg.h.dl;		/* record current column */
X	crow = rg.h.dh;		/* and row */
X
X	/* build the attribute byte and setup the screen pointer */
#if	COLOR
X	if (dtype != CDMONO)
X		attr = (((cbcolor & 15) << 4) | (cfcolor & 15)) << 8;
X	else
X		attr = 0x0700;
#else
X	attr = 0x0700;
#endif
X	lnptr = &sline[0];
X	for (i=0; i < term.t_ncol; i++)
X		*lnptr++ = SPACE | attr;
X
X	if (flickcode && (dtype == CDCGA)) {
X		/* wait for vertical retrace to be off */
X		while ((inp(0x3da) & 8))
X			;
X	
X		/* and to be back on */
X		while ((inp(0x3da) & 8) == 0)
X			;
X	}			
X
X	/* and send the string out */
X	movmem(&sline[0], scptr[crow]+ccol, (term.t_ncol-ccol)*2);
X
}
X
ibmputc(ch)	/* put a character at the current position in the
X		   current colors */
X
int ch;
X
{
X	rg.h.ah = 14;		/* write char to screen with current attrs */
X	rg.h.al = ch;
#if	COLOR
X	if (dtype != CDMONO)
X		rg.h.bl = cfcolor;
X	else
X		rg.h.bl = 0x07;
#else
X	rg.h.bl = 0x07;
#endif
X	int86(0x10, &rg, &rg);
}
X
ibmeeop()
{
X	int attr;		/* attribute to fill screen with */
X
X	rg.h.ah = 6;		/* scroll page up function code */
X	rg.h.al = 0;		/* # lines to scroll (clear it) */
X	rg.x.cx = 0;		/* upper left corner of scroll */
X	rg.x.dx = (term.t_nrow << 8) | (term.t_ncol - 1);
X				/* lower right corner of scroll */
#if	COLOR
X	if (dtype != CDMONO)
X		attr = ((ctrans[gbcolor] & 15) << 4) | (ctrans[gfcolor] & 15);
X	else
X		attr = 0;
#else
X	attr = 0;
#endif
X	rg.h.bh = attr;
X	int86(0x10, &rg, &rg);
}
X
ibmrev(state)		/* change reverse video state */
X
int state;	/* TRUE = reverse, FALSE = normal */
X
{
X	/* This never gets used under the IBM-PC driver */
}
X
ibmcres(res)	/* change screen resolution */
X
char *res;	/* resolution to change to */
X
{
X	int i;		/* index */
X
X	for (i = 0; i < NDRIVE; i++)
X		if (strcmp(res, drvname[i]) == 0) {
X			scinit(i);
X			return(TRUE);
X		}
X	return(FALSE);
}
X
spal()	/* reset the pallette registers */
X
{
X	/* nothin here now..... */
}
X
ibmbeep()
{
#if	MWC86
X	putcnb(BEL);
#else
X	bdos(6, BEL, 0);
#endif
}
X
ibmopen()
{
X	scinit(CDSENSE);
X	revexist = TRUE;
X        ttopen();
}
X
ibmclose()
X
{
#if	COLOR
X	ibmfcol(7);
X	ibmbcol(0);
#endif
X	/* if we had the EGA open... close it */
X	if (dtype == CDEGA)
X		egaclose();
X
X	ttclose();
}
X
ibmkopen()	/* open the keyboard */
X
{
}
X
ibmkclose()	/* close the keyboard */
X
{
}
X
scinit(type)	/* initialize the screen head pointers */
X
int type;	/* type of adapter to init for */
X
{
X	union {
X		long laddr;	/* long form of address */
X		int *paddr;	/* pointer form of address */
X	} addr;
X	int i;
X
X	/* if asked...find out what display is connected */
X	if (type == CDSENSE)
X		type = getboard();
X
X	/* if we have nothing to do....don't do it */
X	if (dtype == type)
X		return(TRUE);
X
X	/* if we try to switch to EGA and there is none, don't */
X	if (type == CDEGA && egaexist != TRUE)
X		return(FALSE);
X
X	/* if we had the EGA open... close it */
X	if (dtype == CDEGA)
X		egaclose();
X
X	/* and set up the various parameters as needed */
X	switch (type) {
X		case CDMONO:	/* Monochrome adapter */
X				scadd = SCADM;
X				newscreensize(25, term.t_ncol);
X				break;
X
X		case CDCGA:	/* Color graphics adapter */
X				scadd = SCADC;
X				newscreensize(25, term.t_ncol);
X				break;
X
X		case CDEGA:	/* Enhanced graphics adapter */
X				scadd = SCADE;
X				egaopen();
X				newscreensize(43, term.t_ncol);
X				break;
X	}
X
X	/* reset the $sres environment variable */
X	strcpy(sres, drvname[type]);
X	dtype = type;
X
X	/* initialize the screen pointer array */
X	for (i = 0; i < NROW; i++) {
X		addr.laddr = scadd + (long)(NCOL * i * 2);
X		scptr[i] = addr.paddr;
X	}
X	return(TRUE);
}
X
/* getboard:	Determine which type of display board is attached.
X		Current known types include:
X
X		CDMONO	Monochrome graphics adapter
X		CDCGA	Color Graphics Adapter
X		CDEGA	Extended graphics Adapter
*/
X
/* getbaord:	Detect the current display adapter
X		if MONO		set to MONO
X		   CGA		set to CGA	EGAexist = FALSE
X		   EGA		set to CGA	EGAexist = TRUE
*/
X
int getboard()
X
{
X	int type;	/* board type to return */
X
X	type = CDCGA;
X	int86(0x11, &rg, &rg);
X	if ((((rg.x.ax >> 4) & 3) == 3))
X		type = CDMONO;
X
X	/* test if EGA present */
X	rg.x.ax = 0x1200;
X	rg.x.bx = 0xff10;
X	int86(0x10,&rg, &rg);		/* If EGA, bh=0-1 and bl=0-3 */
X	egaexist = !(rg.x.bx & 0xfefc);	/* Yes, it's EGA */
X	return(type);
}
X
egaopen()	/* init the computer to work with the EGA */
X
{
X	/* put the beast into EGA 43 row mode */
X	rg.x.ax = 3;
X	int86(16, &rg, &rg);
X
X	rg.h.ah = 17;		/* set char. generator function code */
X	rg.h.al = 18;		/*  to 8 by 8 double dot ROM         */
X	rg.h.bl = 0;		/* block 0                           */
X	int86(16, &rg, &rg);
X
X	rg.h.ah = 18;		/* alternate select function code    */
X	rg.h.al = 0;		/* clear AL for no good reason       */
X	rg.h.bl = 32;		/* alt. print screen routine         */
X	int86(16, &rg, &rg);
X
X	rg.h.ah = 1;		/* set cursor size function code */
X	rg.x.cx = 0x0607;	/* turn cursor on code */
X	int86(0x10, &rg, &rg);
X
X	outp(0x3d4, 10);	/* video bios bug patch */
X	outp(0x3d5, 6);
}
X
egaclose()
X
{
X	/* put the beast into 80 column mode */
X	rg.x.ax = 3;
X	int86(16, &rg, &rg);
}
X
scwrite(row, outstr, forg, bacg)	/* write a line out*/
X
int row;	/* row of screen to place outstr on */
char *outstr;	/* string to write out (must be term.t_ncol long) */
int forg;	/* forground color of string to write */
int bacg;	/* background color */
X
{
X	unsigned int attr;	/* attribute byte mask to place in RAM */
X	unsigned int *lnptr;	/* pointer to the destination line */
X	int i;
X
X	/* build the attribute byte and setup the screen pointer */
#if	COLOR
X	if (dtype != CDMONO)
X		attr = (((ctrans[bacg] & 15) << 4) | (ctrans[forg] & 15)) << 8;
X	else
X		attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
#else
X	attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
#endif
X	lnptr = &sline[0];
X	for (i=0; i<term.t_ncol; i++)
X		*lnptr++ = (outstr[i] & 255) | attr;
X
X	if (flickcode && (dtype == CDCGA)) {
X		/* wait for vertical retrace to be off */
X		while ((inp(0x3da) & 8))
X			;
X	
X		/* and to be back on */
X		while ((inp(0x3da) & 8) == 0)
X			;
X	}
X
X	/* and send the string out */
X	movmem(&sline[0], scptr[row],term.t_ncol*2);
}
X
#if	FLABEL
fnclabel(f, n)		/* label a function key */
X
int f,n;	/* default flag, numeric argument [unused] */
X
{
X	/* on machines with no function keys...don't bother */
X	return(TRUE);
}
#endif
#else
ibmhello()
{
}
#endif
X
SHAR_EOF
chmod 0444 ibmpc.c ||
echo 'restore of ibmpc.c failed'
Wc_c="`wc -c < 'ibmpc.c'`"
test 10074 -eq "$Wc_c" ||
	echo 'ibmpc.c: original size 10074, current size' "$Wc_c"
# ============= input.c ==============
echo 'x - extracting input.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'input.c' &&
/*	INPUT:	Various input routines for MicroEMACS
X		written by Daniel Lawrence
X		5/9/86						*/
X
#include	<stdio.h>
#include	"estruct.h"
#include	"edef.h"
X
/*
X * Ask a yes or no question in the message line. Return either TRUE, FALSE, or
X * ABORT. The ABORT status is returned if the user bumps out of the question
X * with a ^G. Used any time a confirmation is required.
X */
X
mlyesno(prompt)
char *prompt;
{
X	char c;			/* input character */
X
X	for (;;) {
#if     NeWS
X		newsimmediateon() ;
X		mlwrite(,"%s [y/n]? ",prompt);
X		c = tgetc();		/* get the responce */
X		newsimmediateoff() ;
#else
X		mlwrite("%s [y/n]? ",prompt);
X		c = tgetc();		/* get the responce */
#endif
X
X		if (c == kcod2key(abortc))		/* Bail out! */
X			return(ABORT);
X
X		if (c=='y' || c=='Y')
X			return(TRUE);
X
X		if (c=='n' || c=='N')
X			return(FALSE);
X	}
}
X
/*
X * Write a prompt into the message line, then read back a response. Keep
X * track of the physical position of the cursor. If we are in a keyboard
SHAR_EOF
true || echo 'restore of input.c failed'
echo 'End of Vile part 7'
echo 'File input.c is continued in part 8'
echo 8 > _shar_seq_.tmp
exit 0
-- 
		paul fox, pgf at cayman.com, (617)494-1999
		Cayman Systems, 26 Landsdowne St., Cambridge, MA 02139



More information about the Alt.sources mailing list