v08i024: The JOVE text editor, Part05/13

sources-request at mirror.UUCP sources-request at mirror.UUCP
Wed Feb 4 15:03:20 AEST 1987


Submitted by: seismo!rochester!jpayne (Jonathan Payne)
Mod.sources: Volume 8, Issue 24
Archive-name: jove/Part05

#! /bin/sh
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If all goes well, you will see the message "End of archive 5 (of 13)."
# Contents:  jove.c jove.h macros.c malloc.c marks.c setmaps.c
PATH=/bin:/usr/bin:/usr/ucb; export PATH
echo shar: extracting "'jove.c'" '(19628 characters)'
if test -f 'jove.c' ; then 
  echo shar: will not over-write existing file "'jove.c'"
else
sed 's/^X//' >jove.c <<'@//E*O*F jove.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X/* Contains the main loop initializations, and some system dependent
X   type things, e.g. putting terminal in CBREAK mode, etc. */
X
X#include "jove.h"
X#include "io.h"
X#include "termcap.h"
X
X#include <varargs.h>
X#include <sys/stat.h>
X#include <signal.h>
X#include <errno.h>
X#ifndef SYSV
X#include <sgtty.h>
X#else
X#include <termio.h>
X#endif SYSV
X#include <fcntl.h>
X
X#ifdef TIOCSLTC
Xstruct ltchars	ls1,
X		ls2;
X#endif TIOCSLTC
X
X#ifdef TIOCGETC
Xstruct tchars	tc1,
X		tc2;
X#endif
X
X#ifdef BRLUNIX
Xstruct sg_brl	sg1, sg2;
X#else
X#ifdef SYSV
Xstruct termio	sg1, sg2;
X#else SYSV
Xstruct sgttyb	sg1, sg2;
X#endif SYSV
X#endif BRLUNIX
X
X#ifdef BIFF
Xprivate struct stat	tt_stat;	/* for biff */
X#ifndef BSD4_2
Xprivate char	*tt_name = 0;		/* name of the control tty */
Xextern char	*ttyname();		/* for systems w/o fchmod ... */
X#endif
Xprivate int	dw_biff = NO;		/* whether or not to fotz at all */
X#endif
X
Xtime_t	time0;			/* when jove started up */
Xint	errormsg;
Xextern char	*tfname;
Xchar	NullStr[] = "";
X
Xfinish(code)
X{
X	int	CoreDump = (code != 0 && code != SIGHUP),
X		DelTmps = 1;		/* Usually we delete them. */
X
X#ifdef LSRHS
X	if (CoreDump)
X		setdump(1);
X#endif
X	if (code == SIGINT) {
X		char	c;
X
X#ifndef MENLO_JCL
X		(void) signal(code, finish);
X#endif
X		f_mess("Abort (Type 'n' if you're not sure)? ");
X		(void) read(0, &c, 1);
X		message(NullStr);
X		if ((c & 0377) != 'y') {
X			redisplay();
X			return;
X		}
X	}
X	ttyset(OFF);
X	UnsetTerm(NullStr);
X	if (code != 0) {
X		if (!Crashing) {
X			Crashing++;
X			lsave();
X			SyncRec();
X			printf("JOVE CRASH!! (code %d)\n", code);
X			if (ModBufs(1)) {
X				printf("Your buffers have been saved.\n");
X				printf("Use \"jove_recover\" or \"jove -r\"\n");
X				printf("to have a look at them.\n");
X				DelTmps = 0;	/* Don't delete anymore. */
X			} else
X				printf("You didn't lose any work.\n");
X		} else
X			printf("\r\nYou may have lost your work!\n");
X	}
X	flusho();
X	if (DelTmps) {
X		tmpclose();
X		recclose();
X	}
X	if (CoreDump)
X		abort();
X#ifdef PROFILING
X	exit(exp_p);
X#else
X	_exit(exp_p);
X#endif
X}
X
Xprivate char	smbuf[20],
X		*bp = smbuf;
Xprivate int	nchars = 0;
X
Xprivate char	peekbuf[10],
X		*peekp = peekbuf;
X
X#ifdef SYSV
Xvoid
Xsetblock(fd, on)	/* turn blocking on or off */
Xregister int	fd, on;
X{
X    static int blockf, nonblockf;
X    static int first = 1;
X    int flags;
X
X    if (first) {
X	first = 0;
X	if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
X	    finish(SIGHUP);
X	blockf = flags & ~O_NDELAY;	/* make sure O_NDELAY is off */
X	nonblockf = flags | O_NDELAY;	/* make sure O_NDELAY is on */
X    }
X    if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
X	finish(SIGHUP);
X    return;
X}
X#endif SYSV
X
XPeekc()
X{
X	int	c;
X
X	if (peekp == peekbuf)
X		c = -1;
X	else
X		c = *--peekp & 0377;
X	return c;
X}
X
XUngetc(c)
X{
X	if (peekp == &peekbuf[(sizeof peekbuf) - 1])
X		return;		/* Sorry, can't oblige you ... */
X	*peekp++ = c;
X}
X
Xchar	*Inputp = 0;
X
X#ifdef IPROCS
X#ifdef PIPEPROCS
Xgetchar()
X{
X	extern int	errno;
X	register int	c;
X
X	if (nchars <= 0) {
X		do
X			nchars = read(0, smbuf, sizeof smbuf);
X#ifdef SYSV
X		while (nchars == 0 || (nchars < 0 && errno == EINTR));
X		if (nchars < 0)
X#else
X		while (nchars < 0 && errno == EINTR);
X		if (nchars <= 0)
X#endif SYSV
X			finish(SIGHUP);
X		bp = smbuf;
X		InputPending = nchars > 1;
X	}
X	if (((c = *bp) & 0200) && MetaKey != 0) {
X		*bp = (c & 0177);
X		return '\033';
X	}
X	nchars--;
X	return (*bp++ & 0177);
X}
X#else PIPEPROCS
Xgetchar()
X{
X	extern int	global_fd,
X			NumProcs,
X			errno;
X	register int	tmp,
X			nfds;
X	int	reads,
X		c;
X
X	if (nchars <= 0) {
X		/* Get a character from the keyboard, first checking for
X		   any input from a process.  Handle that first, and then
X		   deal with the terminal input. */
X		if (NumProcs > 0) {
X			do {
X				do {
X					reads = global_fd;
X					nfds = select(32, &reads, (int *) 0, (int *) 0, (struct timeval *) 0);
X				} while (nfds < 0 && errno == EINTR);
X
X				switch (nfds) {
X				case -1:
X					printf("\rerror %d in select %d", errno, global_fd);
X					global_fd = 1;
X					break;
X				default:
X					if (reads & 01) {
X						nchars = read(0, smbuf, sizeof(smbuf));
X						reads &= ~01;
X						--nfds;
X					}
X
X					while (nfds--) {
X						tmp = ffs(reads) - 1;
X						read_proc(tmp);
X						reads &= ~tmp;
X					}
X
X					break;
X				}
X			} while (nchars <= 0);
X		} else {
X			do
X				nchars = read(0, smbuf, sizeof(smbuf));
X			while (nchars < 0 && errno == EINTR);
X		}
X
X		if (nchars <= 0)
X			finish(SIGHUP);
X
X		bp = smbuf;
X		InputPending = (nchars > 1);
X	}
X
X	if (((c = *bp) & 0200) && MetaKey != 0) {
X		*bp = (c & 0177);
X		return '\033';
X	}
X	nchars--;
X	return *bp++ & 0377;
X}
X#endif PIPEPROCS
X#else IPROCS
Xgetchar()
X{
X	extern int	errno;
X	register int	c;
X
X	if (nchars <= 0) {
X		do
X			nchars = read(0, smbuf, sizeof smbuf);
X		while (nchars < 0 && errno == EINTR);
X
X		if (nchars <= 0)
X			finish(SIGHUP);
X		bp = smbuf;
X		InputPending = nchars > 1;
X	}
X	if (((c = *bp) & 0200) && MetaKey != 0) {
X		*bp = (c & 0177);
X		return '\033';
X	}
X	nchars--;
X	return *bp++ & 0377;
X}
X#endif IPROCS
X
Xint	InputPending = 0;
X
X/* Returns non-zero if a character waiting */
X
Xcharp()
X{
X	int	some = 0;
X
X	if (InJoverc != 0 || nchars > 0 || Inputp != 0)
X		return 1;
X#ifdef BRLUNIX
X	{
X		static struct sg_brl gttyBuf;
X
X		gtty(0, (char *) &gttyBuf);
X		if (gttyBuf.sg_xflags & INWAIT)
X			some++;
X	}
X#endif
X#ifdef FIONREAD
X	{
X		long c;
X
X		if (ioctl(0, FIONREAD, (struct sgttyb *) &c) == -1)
X			c = 0;
X		some = (c > 0);
X	}
X#endif FIONREAD
X#ifdef SYSV
X	setblock(0, 0);		/* turn blocking off */
X	nchars = read(0, smbuf, sizeof smbuf);	/* Is anything there? */
X	setblock(0, 1);		/* turn blocking on */
X	if (nchars > 0)		/* something was there */
X	    bp = smbuf;		/* make sure bp points to it */
X	some = (nchars > 0);	/* just say we found something */
X#endif SYSV
X#ifdef c70
X	some = !empty(0);
X#endif
X	return some;
X}
X
XResetTerm()
X{
X	putpad(TI, 1);
X	putpad(VS, 1);
X	putpad(KS, 1);
X#ifdef BIFF
X	if (BiffChk != dw_biff)
X		biff_init();
X	/* just in case we changed our minds about whether to deal with
X	   biff */
X#endif
X	(void) chkmail(YES);	/* force it to check to we can be accurate */
X	do_sgtty();		/* this is so if you change baudrate or stuff
X				   like that, JOVE will notice. */
X	ttyset(ON);
X}
X
XUnsetTerm(mesg)
Xchar	*mesg;
X{
X	ttyset(OFF);
X	putpad(KE, 1);
X	putpad(VE, 1);
X	putpad(TE, 1);
X#ifdef ID_CHAR
X	INSmode(0);
X#endif
X	Placur(ILI, 0);
X	printf("%s", mesg);
X	putpad(CE, 1);
X	flusho();
X}
X
X#ifdef JOB_CONTROL
XPauseJove()
X{
X	UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
X	(void) kill(0, SIGTSTP);
X	ResetTerm();
X	ClAndRedraw();
X}
X#endif
X
XPush()
X{
X	int	pid,
X    		(*old_int)() = signal(SIGINT, SIG_IGN),
X		(*old_quit)() = signal(SIGQUIT, SIG_IGN);
X
X#ifdef IPROCS
X	sighold(SIGCHLD);
X#endif
X	switch (pid = fork()) {
X	case -1:
X		complain("[Fork failed]");
X
X	case 0:
X		UnsetTerm(NullStr);
X#ifdef IPROCS
X		sigrelse(SIGCHLD);
X#endif
X		(void) signal(SIGTERM, SIG_DFL);
X		(void) signal(SIGINT, SIG_DFL);
X		(void) signal(SIGQUIT, SIG_DFL);
X		execl(Shell, basename(Shell), (char *)0);
X		message("[Execl failed]");
X		_exit(1);
X	}
X    	dowait(pid, (int *) 0);
X#ifdef IPROCS
X	sigrelse(SIGCHLD);
X#endif
X    	ResetTerm();
X    	ClAndRedraw();
X	(void) signal(SIGQUIT, old_quit);
X    	(void) signal(SIGINT, old_int);
X}
X
Xint	OKXonXoff = 0,		/* ^S and ^Q initially DON'T work */
X	IntChar = CTL(]);
X
Xttsize()
X{
X#ifdef TIOCGWINSZ
X	struct winsize win;
X
X	if (ioctl (0, TIOCGWINSZ, &win) == 0) {
X		if (win.ws_col)
X			CO = win.ws_col;
X		if (win.ws_row)
X			LI = win.ws_row;
X	}
X#else TIOCGWINSZ
X#ifdef BTL_BLIT
X#include <sys/jioctl.h>
X	struct jwinsize jwin;
X
X	if (ioctl(0, JWINSIZE, &jwin) == 0) {
X		if (jwin.bytesx)
X			CO = jwin.bytesx;
X		if (jwin.bytesy)
X			LI = jwin.bytesy;
X	}
X#endif BTL_BLIT
X#endif TIOCGWINSZ
X	ILI = LI - 1;
X}
X
X#ifdef BIFF
Xbiff_init()
X{
X	dw_biff = ((BiffChk) &&
X#ifndef BSD4_2
X		   ((tt_name != 0) || (tt_name = ttyname(0))) &&
X		   (stat(tt_name, &tt_stat) != -1) &&
X#else
X		   (fstat(0, &tt_stat) != -1) &&
X#endif
X		   (tt_stat.st_mode & S_IEXEC));	/* he's using biff */
X
X}
X
Xbiff(on)
X{
X	if (dw_biff == NO)
X		return;
X#ifndef BSD4_2
X	(void) chmod(tt_name, on ? tt_stat.st_mode :
X				   (tt_stat.st_mode & ~S_IEXEC));
X#else
X	(void) fchmod(0, on ? tt_stat.st_mode :
X			      (tt_stat.st_mode & ~S_IEXEC));
X#endif
X}
X
X#endif
X
Xttinit()
X{
X#ifdef BIFF
X	biff_init();
X#endif
X#ifdef TIOCSLTC
X	(void) ioctl(0, TIOCGLTC, (struct sgttyb *) &ls1);
X	ls2 = ls1;
X	ls2.t_suspc = (char) -1;
X	ls2.t_dsuspc = (char) -1;
X	ls2.t_flushc = (char) -1;
X	ls2.t_lnextc = (char) -1;
X#endif
X
X#ifdef TIOCGETC
X	/* Change interupt and quit. */
X	(void) ioctl(0, TIOCGETC, (struct sgttyb *) &tc1);
X	tc2 = tc1;
X	tc2.t_intrc = IntChar;
X	tc2.t_quitc = (char) -1;
X	if (OKXonXoff) {
X		tc2.t_stopc = (char) -1;
X		tc2.t_startc = (char) -1;
X	}
X#endif TIOCGETC
X	do_sgtty();
X}
X
Xprivate int	done_ttinit = 0;
X
Xdo_sgtty()
X{
X#ifdef SYSV
X	(void) ioctl(0, TCGETA, (char *) &sg1);
X#else
X	(void) gtty(0, &sg1);
X#endif SYSV
X	sg2 = sg1;
X
X#ifdef SYSV
X	TABS = !((sg1.c_oflag & TAB3) == TAB3);
X	ospeed = sg1.c_cflag & CBAUD;
X
X	sg2.c_iflag &= ~(INLCR|ICRNL|IGNCR);
X	sg2.c_lflag &= ~(ISIG|ICANON|ECHO);
X	sg2.c_oflag &= ~(OCRNL|ONLCR);
X	sg2.c_cc[VMIN] = sizeof smbuf;
X	sg2.c_cc[VTIME] = 1;
X#else
X	TABS = !(sg1.sg_flags & XTABS);
X	ospeed = sg1.sg_ospeed;
X#ifdef BRLUNIX
X	sg2.sg_flags &= ~(ECHO | CRMOD);
X	sg2.sg_flags |= CBREAK;
X
X	/* VT100 Kludge: leave STALL on for flow control if DC3DC1 (Yuck.) */
X	sg2.sg_xflags &= ~((sg2.sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
X#else
X	sg2.sg_flags &= ~(ECHO | CRMOD);
X#endif BRLUNIX
X
X#ifdef EUNICE
X	sg2.sg_flags |= RAW;	/* Eunice needs RAW mode last I heard. */
X#else
X#ifdef PURDUE_EE
X#   ifdef pdp11
X	sg2.sg_flags |= RAW;
X#   else
X	sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
X#   endif
X#else
X	sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
X#endif PURDUE_EE
X#endif EUNICE
X#endif SYSV
X}
X
Xtty_reset()
X{
X	if (!done_ttinit)
X		return;
X	ttyset(OFF);	/* go back to original modes */
X	ttinit();
X	ttyset(ON);
X}
X
X/* If n is OFF reset to original modes */
X
Xttyset(n)
X{
X	if (!done_ttinit && n == 0)	/* Try to reset before we've set! */
X		return;
X#ifdef SYSV
X	(void) ioctl(0, TCSETAW, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
X#else
X#ifdef BRLUNIX
X	(void) stty(0, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
X#else
X	(void) ioctl(0, TIOCSETN, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
X#endif BRLUNIX
X#endif SYSV
X
X#ifdef TIOCSETC
X	(void) ioctl(0, TIOCSETC, n == 0 ? (struct sgttyb *) &tc1 : (struct sgttyb *) &tc2);
X#endif TIOCSETC
X#ifdef TIOCSLTC
X	(void) ioctl(0, TIOCSLTC, n == 0 ? (struct sgttyb *) &ls1 : (struct sgttyb *) &ls2);
X#endif TIOCSLTC
X	done_ttinit = 1;
X#ifdef BIFF
X	biff(!n);
X#endif
X}
X
Xint	this_cmd,
X	last_cmd;
X
Xdispatch(c)
Xregister int	c;
X{
X	data_obj	*cp;
X
X	this_cmd = 0;
X	cp = mainmap[c & 0177];
X
X	if (cp == 0) {
X		rbell();
X		exp = 1;
X		exp_p = errormsg = NO;
X		message(NullStr);
X	} else
X		ExecCmd(cp);
X}
X
Xint	LastKeyStruck,
X	MetaKey = 0;
X
Xgetch()
X{
X	register int	c,
X			peekc;
X#ifdef IPROCS
X	extern int	NumProcs;
X#endif
X	extern int	ModCount,
X			Interactive;
X
X	if (Inputp) {
X		if ((c = *Inputp++) != 0)
X			return LastKeyStruck = c;
X		Inputp = 0;
X	}
X
X	if (InJoverc)
X		return EOF;	/* somethings wrong if Inputp runs out while
X				   we're reading a .joverc file. */
X
X	if (ModCount >= SyncFreq) {
X		ModCount = 0;
X		SyncRec();
X	}
X
X	/* If we're not interactive and we're not executing a macro,
X	   AND there are no ungetc'd characters, we read from the
X	   terminal (i.e., getch()).  And characters only get put
X	   in macros from inside this if. */
X	if (((peekc = c = Peekc()) == -1) && (Interactive || ((c = mac_getc()) == -1))) {
X		/* So messages that aren't error messages don't
X		   hang around forever. */
X		if (!UpdMesg && !Asking) {	/* Don't erase if we are asking */
X			if (mesgbuf[0] && !errormsg)
X				message(NullStr);
X		}
X		redisplay();
X#ifdef IPROCS
X#  ifdef PIPEPROCS
X		if (NumProcs > 0) {
X			sigrelse(INPUT_SIG);
X			sigrelse(SIGCHLD);
X		}
X#  endif
X#endif
X		inIOread = 1;
X		if ((c = getchar()) == EOF)
X			finish(SIGHUP);
X		inIOread = 0;
X
X#ifdef IPROCS
X#  ifdef PIPEPROCS
X		if (NumProcs > 0) {
X			sighold(INPUT_SIG);
X			sighold(SIGCHLD);
X		}
X#  endif
X#endif
X		if (!Interactive && (KeyMacro.m_flags & DEFINE))
X			mac_putc(c);
X	}
X	if (peekc == -1)	/* Don't add_stroke peekc's */
X		add_stroke(c);
X	return LastKeyStruck = c;
X}
X
Xdorecover()
X{
X	execl(Recover, "jove_recover", "-d", TmpFilePath, (char *)0);
X	printf("%s: execl failed!\n", Recover);
X	flusho();
X	_exit(-1);
X}
X		
X
XShowVersion()
X{
X	extern char	*version;
X
X	s_mess("Jonathan's Own Version of Emacs (%s)", version);
X}
X
XUNIX_cmdline(argc, argv)
Xchar	*argv[];
X{
X	int	lineno = 0,
X		nwinds = 1;
X	Buffer	*b;
X
X	ShowVersion();
X	while (argc > 1) {
X		if (argv[1][0] != '-' && argv[1][0] != '+') {
X			int	force = (nwinds > 0 || lineno != 0);
X
X			minib_add(argv[1], force ? YES : NO);
X			b = do_find(nwinds > 0 ? curwind : (Window *) 0,
X				    argv[1], force);
X			if (force) {
X				SetABuf(curbuf);
X				SetBuf(b);
X				SetLine(next_line(curbuf->b_first, lineno));
X				if (nwinds > 1)
X					NextWindow();
X				if (nwinds)
X					nwinds--;
X			}
X			lineno = 0;
X		} else	switch (argv[1][1]) {
X			case 'd':
X				++argv;
X				--argc;
X				break;
X
X			case 'j':	/* Ignore .joverc in HOME */
X				break;
X
X			case 'p':
X				++argv;
X				--argc;
X				SetBuf(do_find(curwind, argv[1], 0));
X				ParseAll();
X				nwinds = 0;
X				break;
X
X			case 't':
X				++argv;
X				--argc;
X				exp_p = YES;
X				find_tag(argv[1], YES);
X				break;
X
X			case 'w':
X				if (argv[1][2] == '\0')
X					nwinds++;
X				else
X					nwinds += -1 + chr_to_int(&argv[1][2], 10, NIL);
X				(void) div_wind(curwind, nwinds - 1);
X				break;
X
X			case '0':
X			case '1':
X			case '2':
X			case '3':
X			case '4':
X			case '5':
X			case '6':
X			case '7':
X			case '8':
X			case '9':
X				lineno = chr_to_int(&argv[1][1], 10, 0) - 1;
X				break;
X		}
X		++argv;
X		--argc;
X	}
X}
X
X/* VARARGS1 */
X
Xerror(fmt, va_alist)
Xchar	*fmt;
Xva_dcl
X{
X	va_list	ap;
X
X	if (fmt) {
X		va_start(ap);
X		format(mesgbuf, sizeof mesgbuf, fmt, ap);
X		va_end(ap);
X		UpdMesg++;
X	}
X	rbell();
X	(void) longjmp(mainjmp, ERROR);
X}
X
X/* VARARGS1 */
X
Xcomplain(fmt, va_alist)
Xchar	*fmt;
Xva_dcl
X{
X	va_list	ap;
X
X	if (fmt) {
X		va_start(ap);
X		format(mesgbuf, sizeof mesgbuf, fmt, ap);
X		va_end(ap);
X		UpdMesg++;
X	}
X	rbell();
X	(void) longjmp(mainjmp, COMPLAIN);
X}
X
X/* VARARGS1 */
X
Xconfirm(fmt, va_alist)
Xchar	*fmt;
Xva_dcl
X{
X	char	*yorn;
X	va_list	ap;
X
X	va_start(ap);
X	format(mesgbuf, sizeof mesgbuf, fmt, ap);
X	va_end(ap);
X	yorn = ask((char *) 0, mesgbuf);
X	if (*yorn != 'Y' && *yorn != 'y')
X		(void) longjmp(mainjmp, COMPLAIN);
X}
X
Xint	RecDepth = 0;
X
XRecur()
X{
X	char	bname[128];
X	Mark	*m;
X
X	sprintf(bname, "%s", curbuf->b_name);
X	m = MakeMark(curline, curchar, FLOATER);
X
X	RecDepth++;
X	UpdModLine++;
X	DoKeys(1);	/* 1 means not first time */
X	UpdModLine++;
X	RecDepth--;
X	SetBuf(do_select(curwind, bname));
X	if (exp_p == NO)
X		ToMark(m);
X	DelMark(m);
X}
X
Xjmp_buf	mainjmp;
Xint	iniargc;	/* main sets these for DoKeys() */
Xchar	**iniargv;
X
XDoKeys(nocmdline)
X{
X	int	c;
X	jmp_buf	savejmp;
X
X	push_env(savejmp);
X
X	switch (setjmp(mainjmp)) {
X	case 0:
X		if (!nocmdline)
X			UNIX_cmdline(iniargc, iniargv);
X		break;
X
X	case QUIT:
X		if (RecDepth == 0) {
X			if (ModMacs()) {
X				rbell();
X				if (Upper(*ask("No",
X"Some MACROS haven't been saved; leave anyway? ")) != 'Y')
X					break;
X			}
X			if (ModBufs(0)) {
X				rbell();
X				if (Upper(*ask("No",
X"Some buffers haven't been saved; leave anyway? ")) != 'Y')
X					break;
X			}
X#ifdef IPROCS
X			KillProcs();
X#endif
X		}
X		pop_env(savejmp);
X		return;
X
X	case ERROR:
X		getDOT();	/* God knows what state linebuf was in */
X
X	case COMPLAIN:
X		gc_openfiles();	/* close any files we left open */
X		errormsg++;
X		fix_macros();
X		Asking = 0;
X		curwind->w_bufp = curbuf;
X		redisplay();
X		break;
X	}
X
X	this_cmd = last_cmd = 0;
X
X	for (;;) {
X		if (this_cmd != ARG_CMD) {
X			exp = 1;
X			exp_p = NO;
X			last_cmd = this_cmd;
X			init_strokes();
X		}
X		c = getch();
X		if (c == -1)
X			continue;
X	 	dispatch(c);
X	}
X}
X
Xint	Crashing = 0;
X
Xchar **
Xscanvec(args, str)
Xregister char	**args,
X		*str;
X{
X	while (*args) {
X		if (strcmp(*args, str) == 0)
X			return args;
X		args++;
X	}
X	return 0;
X}
X
Xint	UpdFreq = 30,
X	inIOread = 0;
X
Xupdmode()
X{
X	UpdModLine++;
X	if (inIOread)
X		redisplay();
X#ifndef JOB_CONTROL
X	(void) signal(SIGALRM, updmode);
X#endif
X	(void) alarm((unsigned) UpdFreq);
X}
X
X#ifdef TIOCGWINSZ
X#ifdef SIGWINCH
Xextern win_reshape();
X#endif
X#endif
X
X#ifdef TIOCGWINSZ
X#ifdef SIGWINCH
Xwin_reshape()
X{
X	register int diff;
X
X	(void) signal(SIGWINCH, SIG_IGN);
X
X	/*
X	 * Save old number of lines.
X	 */
X	diff = LI;
X
X	/*
X	 * Get new line/col info.
X	 */
X	ttsize();
X
X	/*
X	 * LI has changed, and now holds the
X	 * new value.  See how much the size
X	 * changed.
X	 */
X	diff = LI - diff;
X
X	/*
X	 * Change the size of the current window
X	 * only.  If they shrank by more than
X	 * the window size, tough.
X	 */
X	if ((curwind->w_height + diff) < 2)
X		curwind->w_height = 2;
X	else
X		curwind->w_height += diff;
X
X	make_scr();
X	redisplay();
X
X	(void) signal(SIGWINCH, win_reshape);
X}
X#endif
X#endif
X
Xmain(argc, argv)
Xchar	*argv[];
X{
X	char	ttbuf[512],
X#ifndef VMUNIX
X		s_iobuff[LBSIZE],
X		s_genbuf[LBSIZE],
X		s_linebuf[LBSIZE],
X#endif
X		*cp;
X
X
X#ifndef VMUNIX
X	/* The way I look at it, there ain't no way I is gonna run
X	   out of stack space UNLESS I have some kind of infinite
X	   recursive bug.  So why use up some valuable memory, when
X	   there is plenty of space on the stack?  (This only matters
X	   on wimpy pdp11's, of course.) */
X
X	iobuff = s_iobuff;
X	genbuf = s_genbuf;
X	linebuf = s_linebuf;
X#endif
X
X	errormsg = 0;
X
X	iniargc = argc;
X	iniargv = argv;
X
X	if (setjmp(mainjmp)) {
X		printf("\rAck! I can't deal with error \"%s\" now.\n\r", mesgbuf);
X		finish(0);
X	}
X
X	getTERM();	/* Get terminal. */
X	if (getenv("METAKEY"))
X		MetaKey = 1;
X	ttsize();
X	InitCM();
X
X	d_cache_init();		/* initialize the disk buffer cache */
X
X	if (cp = getenv("SHELL"))
X		strcpy(Shell, cp);
X
X	make_scr();
X	mac_init();	/* Initialize Macros */
X	winit();	/* Initialize Window */
X#ifdef IPROCS
X	pinit();	/* Pipes/process initialization */
X#endif
X	SetBuf(do_select(curwind, Mainbuf));
X
X#ifdef CHDIR
X	{
X		char	**argp;
X
X		if ((argp = scanvec(argv, "-d")) && (argp[1][0] == '/'))
X			setCWD(argp[1]);
X		else
X			getCWD();	/* After we setup curbuf in case we have to getwd() */
X	}
X#endif
X	HomeDir = getenv("HOME");
X	if (HomeDir == 0)
X		HomeDir = "/";
X	HomeLen = strlen(HomeDir);
X#ifdef SYSV
X	sprintf(Mailbox, "/usr/mail/%s", getenv("LOGNAME"));
X#else
X	sprintf(Mailbox, "/usr/spool/mail/%s", getenv("USER"));
X#endif SYSV
X	(void) joverc(Joverc);
X	if (!scanvec(argv, "-j")) {
X		char	tmpbuf[100];
X
X		sprintf(tmpbuf, "%s/.joverc", HomeDir);
X		(void) joverc(tmpbuf);
X	}
X	if (scanvec(argv, "-r"))
X		dorecover();
X
X	(void) time(&time0);
X	ttinit();	/* initialize terminal (after ~/.joverc) */
X	settout(ttbuf);	/* not until we know baudrate */
X	ResetTerm();
X
X	(void) signal(SIGHUP, finish);
X	(void) signal(SIGINT, finish);
X	(void) signal(SIGBUS, finish);
X	(void) signal(SIGSEGV, finish);
X	(void) signal(SIGPIPE, finish);
X	(void) signal(SIGTERM, SIG_IGN);
X#ifdef TIOCGWINSZ
X#ifdef SIGWINCH
X	(void) signal(SIGWINCH, win_reshape);
X#endif
X#endif
X
X	/* set things up to update the modeline every UpdFreq seconds */
X	(void) signal(SIGALRM, updmode);
X	(void) alarm((unsigned) UpdFreq);
X
X	cl_scr(1);
X	flusho();
X	RedrawDisplay();	/* start the redisplay process. */
X	DoKeys(0);
X	finish(0);
X}
@//E*O*F jove.c//
if test 19628 -ne "`wc -c <'jove.c'`"; then
    echo shar: error transmitting "'jove.c'" '(should have been 19628 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'jove.h'" '(14747 characters)'
if test -f 'jove.h' ; then 
  echo shar: will not over-write existing file "'jove.h'"
else
sed 's/^X//' >jove.h <<'@//E*O*F jove.h//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X/* jove.h header file to be included by EVERYONE */
X
X#include <setjmp.h>
X#include <sys/types.h>
X
X#ifndef TUNED
X#   include "tune.h"
X#endif
X
X#define private	static
X
X#ifndef BSD4_2
X#   ifdef MENLO_JCL
X#	ifndef EUNICE
X#		define signal	sigset
X#	endif
X#   endif MENLO_JCL
X#endif
X
X#define EOF	-1
X#define NULL	0
X#define NIL	0
X
X/* kinds of regular expression compiles */
X#define NORM	0	/* nothing special */
X#define OKAY_RE	1	/* allow regular expressions */
X#define IN_CB	2	/* in curly brace; implies OKAY_RE */
X
X/* return codes for command completion (all < 0 because >= 0 are
X   legitimate offsets into array of strings */
X
X#define AMBIGUOUS	-2	/* matches more than one at this point */
X#define UNIQUE		-3	/* matches only one string */
X#define ORIGINAL	-4	/* matches no strings at all! */
X#define NULLSTRING	-5	/* just hit return without typing anything */
X
X/* values for the `flags' argument to complete */
X#define NOTHING		0	/* opposite of RET_STATE */
X#define RET_STATE	1	/* return state when we hit return */
X#define RCOMMAND	2	/* we are reading a joverc file */
X#define CASEIND		4	/* map all to lower case */
X
X#define DEFINE		01	/* defining this macro */
X#define EXECUTE		02	/* executing this macro */
X#define SAVE		04	/* this macro needs saving to a file */
X
X#define	LBSIZE		BUFSIZ	/* same as a logical disk block */
X#define FILESIZE	256
X
X#define FORWARD		1
X#define BACKWARD	-1
X
X#define CTL(c)		('c' & 037)
X#define META(c)		('c' | 0200)
X#define RUBOUT		'\177'
X#define LF		CTL(J)
X#define CR		CTL(M)
X#define BS		CTL(H)
X#define ESC		'\033'
X
X#define DoTimes(f, n)	exp_p = YES, exp = n, f
X#define HALF(wp)	((wp->w_height - 1) / 2)
X#define IsModified(b)	(b->b_modified)
X#define SIZE(wp)	(wp->w_height - 1)
X#define SavLine(a, b)	(a->l_dline = putline(b))
X#define SetLine(line)	DotTo(line, 0)
X#define bobp()		(firstp(curline) && bolp())
X#define bolp()		(curchar == 0)
X#define eobp()		(lastp(curline) && eolp())
X#define eolp()		(linebuf[curchar] == '\0')
X#define firstp(line)	(line == curbuf->b_first)
X#define getDOT()	getline(curline->l_dline, linebuf)
X#define isdirty(line)	(line->l_dline & DIRTY)
X#define lastp(line)	(line == curbuf->b_last)
X#define makedirty(line)	line->l_dline |= DIRTY
X#define one_windp()	(fwind->w_next == fwind)
X
Xextern int	OkayAbort,	/* okay to abort redisplay */
X		BufSize;
X
X#define ARG_CMD		1
X#define LINECMD		2
X#define KILLCMD		3	/* so we can merge kills */
X#define YANKCMD		4	/* so we can do ESC Y (yank-pop) */
X
X/* Buffer type */
X
X#define B_SCRATCH	1	/* for internal things, e.g. minibuffer ... */
X#define B_FILE		2	/* normal file (We Auto-save these.) */
X#define B_PROCESS	3	/* process output in this buffer */
X
X/* Major modes */
X#define FUNDAMENTAL	0	/* Fundamental mode */
X#define TEXT		1	/* Text mode */
X#define CMODE		2	/* C mode */
X#ifdef LISP
X#	define LISPMODE		3	/* Lisp mode */
X#	define NMAJORS		4
X#else
X#	define NMAJORS	3
X#endif
X
X/* Minor Modes */
X#define Indent		(1 << 0)	/* indent same as previous line after return */
X#define ShowMatch	(1 << 1)	/* paren flash mode */
X#define Fill		(1 << 2)	/* text fill mode */
X#define OverWrite	(1 << 3)	/* over write mode */
X#define Abbrev		(1 << 4)	/* abbrev mode */
X
X#define BufMinorMode(b, x)	(b->b_minor & x)
X
X#define MinorMode(x)	BufMinorMode(curbuf, x)
X#define MajorMode(x)	(curbuf->b_major == x)
X#define SetMajor(x)	((curbuf->b_major = x), UpdModLine++)
X
Xextern char	CharTable[NMAJORS][128];
X
X/* setjmp/longjmp args for DoKeys() mainjmp */
X#define FIRSTCALL	0
X#define ERROR		1
X#define COMPLAIN	2	/* do the error without a getDOT */
X#define QUIT		3	/* leave this level of recursion */
X
X#define QUIET		1	/* sure, why not? */
X
X#define YES		1
X#define NO		0
X#define TRUE		1
X#define FALSE		0
X#define ON		1
X#define OFF		0
X#define YES_NODIGIT	2
X
Xextern char	*Mainbuf,
X		*HomeDir,	/* home directory */
X		key_strokes[],	/* strokes that make up current command */
X		*Inputp;
X
Xextern int	HomeLen;	/* length of home directory */
X
Xextern char	NullStr[];
X
X#ifdef VMUNIX
Xextern char	genbuf[LBSIZE],
X		linebuf[LBSIZE],
X		iobuff[LBSIZE];
X#else
Xextern char	*genbuf,	/* scratch pad points at s_genbuf (see main()) */
X		*linebuf,	/* points at s_linebuf */
X		*iobuff;	/* for file reading ... points at s_iobuff */
X#endif
X
Xextern int	InJoverc,
X		Interactive;
X
X#define	READ	0
X#define	WRITE	1
Xextern int	errno;
X
Xextern jmp_buf	mainjmp;
X
X#ifdef IPROCS
Xtypedef struct process	Process;
X#endif
Xtypedef struct window	Window;
Xtypedef struct position	Bufpos;
Xtypedef struct mark	Mark;
Xtypedef struct buffer	Buffer;
Xtypedef struct line	Line;
Xtypedef struct iobuf	IOBUF;
Xtypedef struct data_obj {
X	int	Type;
X	char	*Name;
X} data_obj;	/* points to cmd, macro, or variable */
Xtypedef data_obj	*keymap[0200];
X
Xstruct line {
X	Line	*l_prev,		/* pointer to prev */
X		*l_next;		/* pointer to next */
X	disk_line	l_dline;	/* pointer to disk location */
X};
X
X#ifdef IPROCS
Xstruct process {
X	Process	*p_next;
X#ifdef PIPEPROCS
X	int	p_toproc,	/* read p_fromproc and write p_toproc */
X		p_portpid,	/* Pid of child (the portsrv) */
X		p_pid;		/* Pid of real child i.e. not portsrv */
X#else
X	int	p_fd,		/* File descriptor of ptyp? opened r/w */
X		p_pid;		/* pid of child (the shell) */
X#endif
X	Buffer	*p_buffer;	/* Add output to end of this buffer */
X	char	*p_name;	/* ... */
X	char	p_state,	/* State */
X		p_howdied,	/* Killed? or Exited? */
X		p_reason,	/* If signaled, p_reason is the signal; else
X				   it is the the exit code */
X		p_eof;		/* Received EOF, so can be free'd up */
X	Mark	*p_mark;	/* Where output left us. */
X	data_obj
X		*p_cmd;		/* Command to call when process dies */
X};
X#endif IPROCS
X
Xstruct window {
X	Window	*w_prev,	/* circular list */
X		*w_next;
X	Buffer	*w_bufp;	/* buffer associated with this window */
X	Line	*w_top,		/* top line */
X		*w_line;	/* current line */
X	int	w_char,
X		w_height,	/* window height */
X		w_topnum,	/* line number of the topline */
X		w_dotcol,	/* UpdWindow sets this ... */
X		w_dotline,	/* ... and this */
X		w_flags;
X#define	W_TOPGONE	01
X#define	W_CURGONE	02	/* topline (curline) of window has been deleted
X				   since the last time a redisplay was called */
X#define W_VISSPACE	04
X#define W_NUMLINES	010
X};
X
Xextern Window	*fwind,		/* first window in list */
X		*curwind;	/* current window */
X
Xstruct position {
X	Line	*p_line;
X	int	p_char;
X};
X
Xstruct mark {
X	Line	*m_line;
X	int	m_char;
X	Mark	*m_next;	/* list of marks */
X#define FLOATER	1
X	char	m_floater;	/* FLOATERing mark? */
X};
X
Xstruct buffer {
X	Buffer	*b_next;		/* next buffer in chain */
X	char	*b_name,		/* buffer name */
X		*b_fname;		/* file name associated with buffer */
X	ino_t	b_ino;			/* inode of file name */
X	time_t	b_mtime;		/* last modify time ...
X					   to detect two people writing
X					   to the same file */
X	Line	*b_first,		/* pointer to first line in list */
X		*b_dot,			/* current line */
X		*b_last;		/* last line in list */
X	int	b_char;			/* current character in line */
X
X#define NMARKS	8			/* number of marks in the ring */
X
X	Mark	*b_markring[NMARKS],	/* new marks are pushed saved here */
X		*b_marks;		/* all the marks for this buffer */
X	char	b_themark,		/* current mark (in b_markring) */
X		b_type,			/* file, scratch, process, iprocess */
X		b_ntbf,			/* needs to be found when we
X					   first select? */
X		b_modified;		/* is the buffer modified? */
X	int	b_major,		/* major mode */
X		b_minor;		/* and minor mode */
X	keymap	*b_keybinds;		/* local bindings (if any) */
X#ifdef IPROCS
X	Process	*b_process;		/* process we're attached to */
X#endif
X};
X
Xstruct macro {
X	int	Type;		/* in this case a macro */
X	char	*Name;		/* name is always second ... */
X	int	m_len,		/* length of macro so we can use ^@ */
X		m_buflen,	/* memory allocated for it */
X		m_offset,	/* index into body for defining and running */
X		m_flags,	/* defining/running this macro? */
X		m_ntimes;	/* number of times to run this macro */
X	char	*m_body;	/* actual body of the macro */
X	struct macro
X		*m_nextm;
X};
X
Xstruct variable {
X	int	Type;		/* in this case a variable */
X	char	*Name;		/* name is always second */
X	int	*v_value,
X		v_flags;
X};
X
Xstruct cmd {
X	int	Type;
X	char	*Name;
X	int	(*c_proc)();
X};
X
Xextern keymap	mainmap,	/* various key maps */
X		pref1map,
X		pref2map,
X		miscmap;
X
Xextern data_obj	*LastCmd;	/* last command invoked */
X
Xextern char	*ProcFmt;
X
Xextern struct cmd	commands[];
Xextern struct macro	*macros;
Xextern struct variable	variables[];
X
Xextern struct macro
X	*macstack[],
X	KeyMacro;
X
X#define FUNCTION	1
X#define VARIABLE	2
X#define MACRO		3
X#define TYPEMASK	07
X#define MAJOR_MODE	010
X#define MINOR_MODE	020
X#define DefMajor(x)	(FUNCTION|MAJOR_MODE|(x << 8))
X#define DefMinor(x)	(FUNCTION|MINOR_MODE|(x << 8))
X
Xextern Buffer	*world,		/* first buffer */
X		*curbuf;	/* pointer into world for current buffer */
X
X#define curline	curbuf->b_dot
X#define curchar curbuf->b_char
X
X#define NUMKILLS	10	/* number of kills saved in the kill ring */
X
X#define DIRTY		01	/* just needs updating for some reason */
X#define MODELINE	02	/* this is a modeline */
X#define L_MOD		04	/* this line has been modified internally */
X
Xstruct scrimage {
X	int	s_offset,	/* offset to start printing at */
X		s_flags,	/* various flags */
X		s_id,		/* which buffer line */
X		s_vln;		/* Visible Line Number */
X	Line	*s_lp;		/* so we can turn off red bit */
X	Window	*s_window;	/* window that contains this line */
X};
X
Xextern struct scrimage
X	*DesiredScreen,		/* what we want */
X	*PhysScreen;		/* what we got */
X
X/* Variable flags (that can be set). */
X#define V_BASE10	01	/* is integer in base 10 */
X#define V_BASE8		02	/* is integer in base 8 */
X#define V_BOOL		04	/* is a boolean */
X#define V_STRING	010	/* is a string */
X#define V_CHAR		020	/* is a character */
X#define V_FILENAME	040	/* a file name (implies V_STRING) */
X#define V_TYPEMASK	077	/* mask off the extra bits */
X#define V_MODELINE	0100	/* update modeline */
X#define V_CLRSCREEN	0200	/* clear and redraw screen */
X#define V_TTY_RESET	0400	/* redo the tty modes */
X
Xextern int
X	OKXonXoff,		/* disable start/stop characters */
X	MetaKey,		/* this terminal has a meta key */
X	VisBell,		/* use visible bell (if possible) */
X	WrapScan,		/* make searches wrap */
X	phystab,		/* terminal's tabstop settings */ 
X	tabstop,		/* expand tabs to this number of spaces */
X#ifdef BACKUPFILES
X	BkupOnWrite,		/* make backup files when writing */
X#endif
X	RMargin,		/* right margin */
X	LMargin,		/* left margin */
X	ScrollStep,		/* how should we scroll */
X	WtOnMk,			/* write files on compile-it command */
X	EndWNewline,		/* end files with a blank line */
X	MarkThresh,		/* moves greater than MarkThresh
X				   will SetMark */
X	PDelay,			/* paren flash delay in tenths of a second */
X	CIndIncrmt,		/* how much each indentation level pushes
X				   over in C mode */
X	CreatMode,		/* default mode for creat'ing files */
X	CaseIgnore,		/* case ignore search */
X#ifdef ABBREV
X	AutoCaseAbbrev,		/* automatically do case on abbreviations */
X#endif
X	MarksShouldFloat,	/* adjust marks on insertion/deletion */
X	UseRE,			/* use regular expressions in search */
X	SyncFreq,		/* how often to sync the file pointers */
X	BriteMode,		/* make the mode line inverse? */
X	OkayBadChars,		/* allow bad characters in files created
X				   by JOVE */
X	UpdFreq,		/* how often to update modeline */
X	UseBuffers,		/* use buffers with Typeout() */
X#ifdef BIFF
X	BiffChk,		/* turn off/on biff with entering/exiting jove */
X#endif
X	MailInt,		/* mail check interval */
X#ifdef ID_CHAR
X	UseIC,			/* whether or not to use i/d char
X				   processesing */
X	SExitChar,		/* type this to stop i-search */
X#endif
X	IntChar,		/* ttysets this to generate QUIT */
X	EWSize;			/* size to make the error window */
X
Xextern char
X#ifdef IPROCS
X	proc_prompt[80],	/* process prompt */
X#endif
X#ifdef F_COMPLETION
X	BadExtensions[128],	/* extensions (e.g., ".o" to ignore) */
X#endif
X#ifdef CMT_FMT
X	CmtFmt[80],
X#endif
X	ModeFmt[120],		/* mode line format string */
X	Mailbox[128],		/* mailbox name */
X	TmpFilePath[128],	/* directory/device to store tmp files */
X	TagFile[128],		/* default tag file */
X	Shell[128];		/* shell to use */
X
Xextern int
X	exp,		/* argument count */
X	exp_p,		/* argument count is supplied */
X
X	TOabort,	/* flag set by Typeout() */
X	io,		/* file descriptor for reading and writing files */
X	errormsg,	/* last message was an error message
X			   so don't erase the error before it
X			   has been read */
X	this_cmd,	/* ... */
X	last_cmd,	/* last command ... to implement appending
X			   to kill buffer */
X	RecDepth,	/* recursion depth */
X	InputPending,	/* nonzero if there is input waiting to
X			   be processed */
X 	killptr,	/* index into killbuf */
X	CanScroll,	/* can this terminal scroll? */
X	Crashing,	/* we are in the middle of crashing */
X	Asking,		/* are we on read a string from the terminal? */
X	inIOread;	/* so we know whether we can do a redisplay. */
X
Xextern char	Minibuf[LBSIZE];
X
X#define curmark		(curbuf->b_markring[curbuf->b_themark])
X#define b_curmark(b)	(b->b_markring[b->b_themark])
X
Xextern Line	*killbuf[NUMKILLS];	/* array of pointers to killed stuff */
X
X#define MESG_SIZE 128
Xextern char	mesgbuf[MESG_SIZE];
X
Xstruct screenline {
X	char	*s_line,
X		*s_length;
X};
X
Xextern int
X	LastKeyStruck;
X
Xextern int
X	stackp,
X
X	CapLine,	/* cursor line and cursor column */
X	CapCol,
X
X	UpdModLine,	/* whether we want to update the mode line */
X	UpdMesg;	/* update the message line */
X
X#define CATCH \
X{\
X	jmp_buf	sav_jmp; \
X\
X	push_env(sav_jmp); \
X	if (setjmp(mainjmp) == 0) {
X
X#define ONERROR \
X	} else { \
X
X#define ENDCATCH \
X	} \
X	pop_env(sav_jmp); \
X}
X
Xextern int
X	read(),
X	write();
X	getch();
X
Xextern time_t	time();
Xextern long	lseek();
X
Xextern disk_line
X	putline();
X
Xextern data_obj
X	*findcom(),
X	*findvar(),
X	*findmac();
X
Xextern Line
X	*next_line(),
X	*prev_line(),
X	*nbufline(),
X	*reg_delete(),
X	*lastline(),
X	*listput();
X
Xextern char
X	*getsearch(),
X	*pwd(),
X	*itoa(),
X	*get_time(),
X	*copystr(),
X	*basename(),
X	*filename(),
X	*IOerr(),
X	*index(),
X	*ask(),
X	*do_ask(),
X	*ask_buf(),
X	*ask_file(),
X	*lcontents(),
X	*malloc(),
X	*emalloc(),
X	*mktemp(),
X	*realloc(),
X	*ltobuf(),
X	*lbptr(),
X	*rindex(),
X	*getenv(),
X	*tgoto(),
X	*pr_name(),
X	*sprint(),
X	*StrIndex();
X
Xextern Bufpos
X	*docompiled(),
X	*dosearch(),
X	*DoYank(),
X	*c_indent(),
X#ifdef LISP
X	*lisp_indent(),
X#endif
X	*m_paren();
X
Xextern Mark
X	*CurMark(),
X	*MakeMark();
X
Xextern Window
X	*windbp(),
X	*div_wind();
X
Xextern data_obj
X	**IsPrefix();
X
Xextern Buffer
X	*do_find(),
X	*do_select(),
X	*mak_buf(),
X	*buf_exists(),
X	*file_exists();
X
Xstruct cmd *
X	FindCmd();
@//E*O*F jove.h//
if test 14747 -ne "`wc -c <'jove.h'`"; then
    echo shar: error transmitting "'jove.h'" '(should have been 14747 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'macros.c'" '(9026 characters)'
if test -f 'macros.c' ; then 
  echo shar: will not over-write existing file "'macros.c'"
else
sed 's/^X//' >macros.c <<'@//E*O*F macros.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X#include "jove.h"
X
Xstruct macro	*macros = 0;		/* Macros */
Xdata_obj	*LastCmd;
X
Xprivate
Xadd_mac(new)
Xstruct macro	*new;
X{
X	register struct macro	*mp,
X				*prev = 0;
X
X	for (mp = macros; mp != 0; prev = mp, mp = mp->m_nextm)
X		if (mp == new)
X			return;
X
X	if (prev)
X		prev->m_nextm = new;
X	else
X		macros = new;
X	new->m_nextm = 0;
X	new->Type = MACRO;
X}
X
Xprivate
Xdel_mac(mac)
Xstruct macro	*mac;
X{
X	register struct macro	*m;
X
X	for (m = macros; m != 0; m = m->m_nextm)
X		if (m->m_nextm == mac) {
X			m->m_nextm = mac->m_nextm;
X			break;
X		}
X	free(mac->Name);
X	free(mac->m_body);
X	free((char *) mac);
X}
X
Xstruct macro	KeyMacro;	/* Macro used for defining */
X
X#define NMACROS	40		/* This is bad, bad, BAD! */
X
Xstruct macro	*macstack[NMACROS];
Xprivate int	stackp = 0;
X
Xfix_macros()
X{
X	register int	i;
X	register struct macro	*mp;
X
X	for (i = 0; macstack[i]; i++) {
X		mp = macstack[i];
X		macstack[i] = 0;
X		mp->m_flags = mp->m_offset = 0;
X	}
X	stackp = -1;
X	KeyMacro.m_flags = KeyMacro.m_offset = 0;
X}
X
Xprivate
Xmac_err(err)
Xchar	*err;
X{
X	KeyMacro.m_flags = 0;
X	MacNolen(&KeyMacro);
X	complain(err);
X}
X
Xdo_macro(mac)
Xstruct macro	*mac;
X{
X	if (mac->m_flags & EXECUTE)
X		mac_err("[Attempt to execute macro recursively!]");
X	if (++stackp >= NMACROS)
X		complain("[Too many macros at once!]");
X	macstack[stackp] = mac;
X	mac->m_offset = 0;
X	mac->m_ntimes = exp;
X	mac->m_flags |= EXECUTE;
X}
X
Xprivate
XMacNolen(m)
Xstruct macro	*m;
X{
X	m->m_len = m->m_offset = 0;
X}
X
Xprivate struct macro *
Xmac_exists(name)
Xchar	*name;
X{
X	register struct macro	*mp;
X
X	for (mp = macros; mp; mp = mp->m_nextm)
X		if (strcmp(mp->Name, name) == 0)
X			return mp;
X	return 0;
X}
X
Xmac_init()
X{
X	add_mac(&KeyMacro);
X	MacNolen(&KeyMacro);
X	KeyMacro.Name = "keyboard-macro";
X	KeyMacro.m_buflen = 16;
X	KeyMacro.m_body = emalloc(KeyMacro.m_buflen);
X	KeyMacro.m_ntimes = KeyMacro.m_flags = 0;
X	fix_macros();
X}
X
Xmac_putc(c)
Xint	c;
X{
X	if (KeyMacro.m_len >= KeyMacro.m_buflen) {
X		KeyMacro.m_buflen += 16;
X		KeyMacro.m_body = realloc(KeyMacro.m_body, (unsigned) KeyMacro.m_buflen);
X		if (KeyMacro.m_body == 0)
X			mac_err("[Can't allocate storage for keyboard macro]");
X	}
X	KeyMacro.m_body[KeyMacro.m_offset++] = c;
X	KeyMacro.m_len++;
X}
X
Xin_macro()
X{
X	return ((stackp >= 0) && ((macstack[stackp])->m_flags & EXECUTE));
X}
X
Xmac_getc()
X{
X	struct macro	*m;
X
X	if (stackp < 0 || ((m = macstack[stackp])->m_flags & EXECUTE) == 0)
X		return -1;
X	if (m->m_offset == m->m_len) {
X		m->m_offset = 0;
X		if (--m->m_ntimes == 0) {
X			m->m_flags &= ~EXECUTE;
X			stackp--;
X		}
X		return mac_getc();
X	}
X	return m->m_body[m->m_offset++];
X}
X
XNameMac()
X{
X	char	*name;
X	struct macro	*m;
X
X	if (KeyMacro.m_len == 0)
X		complain("[No keyboard macro to name!]");
X	if (KeyMacro.m_flags & (DEFINE | EXECUTE))
X		complain("[Can't name while defining/executing]");
X	if ((m = mac_exists(name = ask((char *) 0, ProcFmt))) == 0)
X		m = (struct macro *) emalloc(sizeof *m);
X	else {
X		if (strcmp(name, KeyMacro.Name) == 0)
X			complain("[Can't name it that!]");
X		free(m->Name);
X		free(m->m_body);
X	}
X	name = copystr(name);
X	m->Type = KeyMacro.Type;
X	m->m_len = KeyMacro.m_len;
X	m->m_buflen = KeyMacro.m_buflen;
X	m->m_body = emalloc(m->m_buflen);
X	byte_copy(KeyMacro.m_body, m->m_body, m->m_len);
X	m->m_ntimes = m->m_offset = 0;	/* At the beginning */
X	m->m_flags = SAVE;
X	m->Name = name;
X	add_mac(m);
X}	
X
XRunMacro()
X{
X	struct macro	*m;
X
X	if (m = (struct macro *) findmac(ProcFmt))
X		do_macro(m);
X}
X
Xprivate int	mac_fd;
X
Xprivate
Xmac_io(fcn, ptr, nbytes)
Xint	(*fcn)();
Xchar	*ptr;
X{
X	int	nio;
X
X	if ((nio = (*fcn)(mac_fd, ptr, nbytes)) != nbytes)
X		complain("[Macro %s error: %d got %d]",
X			 (fcn == read) ? "read" : "write",
X			 nbytes,
X			 nio);
X}
X
XWriteMacs()
X{
X	struct macro	*m;
X	int	namelen,
X		netl,
X		nmacs = 0;
X	char	*file,
X		filebuf[FILESIZE];
X	long htonl() ;
X
X	file = ask_file((char *) 0, (char *) 0, filebuf);
X	if ((mac_fd = creat(file, 0666)) == -1)
X		complain(IOerr("create", file));
X	f_mess("\"%s\"", file);
X
X	/* Don't write the keyboard macro which is always the first */
X	for (m = macros->m_nextm; m != 0; m = m->m_nextm) {
X		if (m->m_len == 0)
X			continue;
X		nmacs++;
X		netl = htonl(m->m_len);
X		mac_io(write, (char *) &netl, sizeof m->m_len);
X		namelen = strlen(m->Name) + 1;	/* Including the null */
X		netl = htonl(namelen);
X		mac_io(write, (char *) &netl, sizeof namelen);
X		mac_io(write, m->Name, namelen);
X		mac_io(write, m->m_body, m->m_len);
X		m->m_flags &= ~SAVE;
X	}
X	(void) close(mac_fd);
X	add_mess(" %d macro%n saved.", nmacs, nmacs);
X}
X
X#define NEWWAY	1
X#define OLDWAY	0
X
Xprivate int	int_how = NEWWAY;
X
X/* Formatting int's the old way or the new "improved" way? */
X
X#if vax || pdp11
Xlong htonl(x)
Xregister long x;
X{
X	return(	(((x >>  0) & 0377) << 24) |
X		(((x >>  8) & 0377) << 16) |
X		(((x >> 16) & 0377) <<  8) |
X		(((x >> 24) & 0377) <<  0) );
X}
X
Xshort htons(x)
Xregister short x;
X{
X	return(	(((x >>  0) & 0377) << 8) |
X		(((x >>  8) & 0377) << 0) );
X}
X
Xlong ntohl(x)
Xregister long x;
X{
X	return(	(((x >>  0) & 0377) << 24) |
X		(((x >>  8) & 0377) << 16) |
X		(((x >> 16) & 0377) <<  8) |
X		(((x >> 24) & 0377) <<  0) );
X}
X
Xshort ntohs(x)
Xregister short x;
X{
X	return(	(((x >>  0) & 0377) << 8) |
X		(((x >>  8) & 0377) << 0) );
X}
X#else
Xlong htonl(x)
Xregister long x;
X{
X	return(x);
X}
X
Xshort htons(x)
Xregister short x;
X{
X	return(x);
X}
X
Xlong ntohl(x)
Xregister long x;
X{
X	return(x);
X}
X
Xshort ntohs(x)
Xregister short x;
X{
X	return(x);
X}
X#endif
X
Xint_fmt(i)
X{
X	if (int_how == NEWWAY)
X		return ntohl(i);
X	return i;
X}
X
XReadMacs()
X{
X	char	*file,
X		filebuf[FILESIZE];
X	struct macro	*m;
X	int	nmacs = 0,
X		namelen,
X		bodylen,
X		tmp,
X		he_is_sure = 0,
X		save_em = FALSE;
X
X	file = ask_file((char *) 0, (char *) 0, filebuf);
X	if ((mac_fd = open(file, 0)) == -1)
X		complain(IOerr("open", file));
X
X	f_mess("\"%s\"", file);
X	while (read(mac_fd, (char *) &tmp, sizeof tmp) == (sizeof tmp)) {
Xretry:		bodylen = int_fmt(tmp);
X		if (!he_is_sure && (bodylen <= 0 || bodylen > 10000)) {
X			if (int_how == NEWWAY) {
X				int_how = OLDWAY;
X				save_em = TRUE;
X				goto retry;
X			} else {
X				confirm("Are you sure \"%s\" is a JOVE macro file? ", filebuf);
X				he_is_sure = 1;
X			}
X		}
X		nmacs++;
X		m = (struct macro *) emalloc (sizeof *m);
X		m->m_flags = 0;
X		m->m_len = bodylen;
X		m->m_buflen = m->m_len;
X		mac_io(read, (char *) &namelen, sizeof namelen);
X		namelen = int_fmt(namelen);
X		m->Name = emalloc(namelen);
X		mac_io(read, m->Name, namelen);
X		m->m_body = emalloc(m->m_buflen);
X		mac_io(read, m->m_body, m->m_len);
X		add_mac(m);
X	}
X	(void) close(mac_fd);
X	add_mess(" %d macro%n defined.", nmacs, nmacs);
X	if (save_em) {
X		char	*msg = "OK to convert to the new format? ",
X			ibuf[FILESIZE + 1];
X
X		if (!InJoverc) {
X			TOstart("Warning", TRUE);
X			Typeout("Warning: your macros file is in the old format.");
X			Typeout("Do you want me to convert \"%s\" to the new", pr_name(file));
X			Typeout("format?");
X			f_mess(msg);
X			TOstop();
X			confirm(msg);
X		}
X		/* WriteMacs requests a file name.  This is what it'll get. */
X		sprintf(ibuf, "%s\n", file);
X		Inputp = ibuf;
X		WriteMacs();
X	}		
X}
X
XRemember()
X{
X	if (KeyMacro.m_flags & EXECUTE)
X		/* We're already executing the macro; ignore any attempts
X		   to define the keyboard macro while we are executing. */
X		return;
X	if (KeyMacro.m_flags & DEFINE)
X		message("[Already remembering ... continue with definition]");
X	else {
X		UpdModLine++;
X		KeyMacro.m_flags |= DEFINE;
X		MacNolen(&KeyMacro);
X		message("Remembering...");
X	}
X}
X
X/* Is `c' a prefix character */
X
Xprivate
XPrefChar(c)
X{
X	return (int) IsPrefix(mainmap[c]);
X}
X
XForget()
X{
X	char	*cp;
X	struct macro	*m = &KeyMacro;
X
X	UpdModLine++;
X	if (m->m_flags & DEFINE) {
X		message("Keyboard macro defined.");
X		m->m_flags &= ~DEFINE;
X		cp = &m->m_body[m->m_len - 2];
X		if (PrefChar(*cp))
X			m->m_len -= 2;
X		else if (commands[*++cp].c_proc == Forget)
X			m->m_len--;
X	}
X}
X
XExecMacro()
X{
X	do_macro(&KeyMacro);
X}
X
XMacInter()
X{
X	extern int	Interactive;
X
X	if (!Asking)
X		return;
X	Interactive = 1;
X}
X
XModMacs()
X{
X	register struct macro	*m;
X
X	for (m = macros->m_nextm; m != 0; m = m->m_nextm)
X		if (m->m_flags & SAVE)
X			return 1;
X	return 0;
X}
X
Xdata_obj *
Xfindmac(prompt)
Xchar	*prompt;
X{
X	char	*strings[100];
X	register char	**strs = strings;
X	register int	com;
X	register struct macro	*m = macros;
X
X	for (; m != 0; m = m->m_nextm)
X		*strs++ = m->Name;
X	*strs = 0;
X
X	if ((com = complete(strings, prompt, NOTHING)) < 0)
X		return 0;
X	m = macros;
X	while (--com >= 0)
X		m = m->m_nextm;
X	return (data_obj *) m;
X}
X
XDelMacro()
X{
X	struct macro	*m;
X
X	if ((m = (struct macro *) findmac(ProcFmt)) == 0)
X		return;
X	if (m == &KeyMacro)
X		complain("[It's illegal to delete the keyboard-macro!]");
X	del_mac(m);
X}
@//E*O*F macros.c//
if test 9026 -ne "`wc -c <'macros.c'`"; then
    echo shar: error transmitting "'macros.c'" '(should have been 9026 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'malloc.c'" '(4003 characters)'
if test -f 'malloc.c' ; then 
  echo shar: will not over-write existing file "'malloc.c'"
else
sed 's/^X//' >malloc.c <<'@//E*O*F malloc.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X#include "tune.h"
X
X#ifdef MY_MALLOC
X
X/*	avoid break bug */
X#ifdef pdp11
X#	define GRANULE 64
X#else
X#	define GRANULE 0
X#endif
X
X/*	C storage allocator
X *	circular first-fit strategy
X *	works with noncontiguous, but monotonically linked, arena
X *	each block is preceded by a ptr to the (pointer of) 
X *	the next following block
X *	blocks are exact number of words long 
X *	aligned to the data type requirements of ALIGN
X *	pointers to blocks must have BUSY bit 0
X *	bit in ptr is 1 for busy, 0 for idle
X *	gaps in arena are merely noted as busy blocks
X *	last block of arena (pointed to by alloct) is empty and
X *	has a pointer to first
X *	idle blocks are coalesced during space search
X *
X *	a different implementation may need to redefine
X *	ALIGN, NALIGN, BLOCK, BUSY, INT
X *	where INT is integer type to which a pointer can be cast
X */
X
X#define INT		int
X#define ALIGN		int
X#define NALIGN		1
X#define WORD		sizeof(union store)
X#define BLOCK		1024	/* a multiple of WORD*/
X#define BUSY		1
X#define NULL		0
X#define testbusy(p)	((INT)(p)&BUSY)
X#define setbusy(p)	(union store *) ((INT) (p) | BUSY)
X#define clearbusy(p)	(union store *) ((INT) (p) &~ BUSY)
X
Xunion store {
X	union store	*ptr;
X	ALIGN	dummy[NALIGN];
X	int	calloc;		/*calloc clears an array of integers*/
X};
X
Xstatic union store	allocs[2],	/*initial arena*/
X			*allocp,	/*search ptr*/
X			*alloct,	/*arena top*/
X			*allocx;	/*for benefit of realloc*/
X
Xchar	*sbrk();
X
Xchar *
Xmalloc(nbytes)
Xunsigned int	nbytes;
X{
X	register union store	*p,
X				*q;
X	register int	nw;
X	static int	temp;	/* coroutines assume no auto */
X
X	if (allocs[0].ptr == 0) {	/* first time */
X		allocs[0].ptr = setbusy(&allocs[1]);
X		allocs[1].ptr = setbusy(&allocs[0]);
X		alloct = &allocs[1];
X		allocp = &allocs[0];
X	}
X	nw = (nbytes + WORD + WORD - 1) / WORD;
X	for (p = allocp; ; ) {
X		for (temp = 0; ; ) {
X			if (!testbusy(p->ptr)) {
X				while (!testbusy((q = p->ptr)->ptr))
X					p->ptr = q->ptr;
X				if(q >= p + nw && p + nw >= p)
X					goto found;
X			}
X			q = p;
X			p = clearbusy(p->ptr);
X			if (p > q)
X				;
X			else if (q != alloct || p != allocs)
X				return NULL;
X			else if (++temp > 1)
X				break;
X		}
X		temp = ((nw + BLOCK/WORD) / (BLOCK/WORD)) * (BLOCK/WORD);
X		q = (union store *) sbrk(0);
X		if (q + temp + GRANULE < q)
X			return NULL;
X		q = (union store *) sbrk(temp * WORD);
X		if ((INT) q == -1)
X			return NULL;
X		alloct->ptr = q;
X		if (q != alloct+1)
X			alloct->ptr = setbusy(alloct->ptr);
X		alloct = q->ptr = q + temp - 1;
X		alloct->ptr = setbusy(allocs);
X	}
Xfound:
X	allocp = p + nw;
X	if (q > allocp) {
X		allocx = allocp->ptr;
X		allocp->ptr = p->ptr;
X	}
X	p->ptr = setbusy(allocp);
X	return (char *) (p + 1);
X}
X
X/* freeing strategy tuned for LIFO allocation */
X
Xfree(ap)
Xregister char	*ap;
X{
X	register union store	*p = (union store *) ap;
X
X	allocp = --p;
X	p->ptr = clearbusy(p->ptr);
X}
X
X/*	realloc(p, nbytes) reallocates a block obtained from malloc()
X *	and freed since last call of malloc()
X *	to have new size nbytes, and old content
X *	returns new location, or 0 on failure
X*/
X
Xchar *
Xrealloc(obj, nbytes)
Xchar	*obj;
Xunsigned int	nbytes;
X{
X	register union store	*q,
X				*p = (union store *) obj;
X	union store	*s,
X			*t;
X	register unsigned int	nw;
X	unsigned int	onw;
X
X	if (testbusy(p[-1].ptr))
X		free((char *) p);
X	onw = p[-1].ptr - p;
X	q = (union store *) malloc(nbytes);
X	if(q == NULL || q == p)
X		return((char *) q);
X	s = p;
X	t = q;
X	nw = (nbytes + WORD - 1)/WORD;
X	if (nw < onw)
X		onw = nw;
X	while (onw-- != 0)
X		*t++ = *s++;
X	if(q < p && q + nw >= p)
X		(q + (q+nw-p))->ptr = allocx;
X	return (char *) q;
X}
X
X#endif MY_MALLOC
@//E*O*F malloc.c//
if test 4003 -ne "`wc -c <'malloc.c'`"; then
    echo shar: error transmitting "'malloc.c'" '(should have been 4003 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'marks.c'" '(4197 characters)'
if test -f 'marks.c' ; then 
  echo shar: will not over-write existing file "'marks.c'"
else
sed 's/^X//' >marks.c <<'@//E*O*F marks.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
Xint	MarksShouldFloat = 1;
X
X#include "jove.h"
X
XMark *
XMakeMark(line, column, type)
Xregister Line	*line;
X{
X	register Mark	*newmark = (Mark *) emalloc(sizeof *newmark);
X
X	MarkSet(newmark, line, column);
X	newmark->m_next = curbuf->b_marks;
X	newmark->m_floater = type;
X	curbuf->b_marks = newmark;
X	return newmark;
X}
X
XDelMark(m)
Xregister Mark	*m;
X{
X	register Mark	*mp = curbuf->b_marks;
X
X	if (m == mp)
X		curbuf->b_marks = m->m_next;
X	else {
X		while (mp != 0 && mp->m_next != m)
X			mp = mp->m_next;
X		if (mp == 0)
X			complain("Unknown mark!");
X		mp->m_next = m->m_next;
X	}
X	free((char *) m);
X}
X
XAllMarkSet(b, line, col)
XBuffer	*b;
Xregister Line	*line;
X{
X	register Mark	*mp;
X
X	for (mp = b->b_marks; mp != 0; mp = mp->m_next)
X		MarkSet(mp, line, col);
X}
X
XMarkSet(m, line, column)
XMark	*m;
XLine	*line;
X{
X	m->m_line = line;
X	m->m_char = column;
X}
X
XPopMark()
X{
X	int	pmark;
X
X	if (curmark == 0)
X		return;
X	if (curbuf->b_markring[(curbuf->b_themark + 1) % NMARKS] == 0) {
X		pmark = curbuf->b_themark;
X		do {
X			if (--pmark < 0)
X				pmark = NMARKS - 1;
X		} while (curbuf->b_markring[pmark] != 0);
X
X		curbuf->b_markring[pmark] = MakeMark(curline, curchar, MarksShouldFloat);
X		ToMark(curmark);
X		DelMark(curmark);
X		curmark = 0;
X	} else
X		PtToMark();
X
X	pmark = curbuf->b_themark - 1;
X	if (pmark < 0)
X		pmark = NMARKS - 1;
X	curbuf->b_themark = pmark;
X}
X
XSetMark()
X{
X	if (exp_p)
X		PopMark();
X	else
X		DoSetMark(curline, curchar);
X}
X
XDoSetMark(l, c)
XLine	*l;
X{
X	curbuf->b_themark = (curbuf->b_themark + 1) % NMARKS;
X	if (curmark == 0)
X		curmark = MakeMark(l, c, MarksShouldFloat);
X	else
X		MarkSet(curmark, l, c);
X	s_mess("[Point pushed]");
X}
X
X/* Move point to Mark */
X
XToMark(m)
XMark	*m;
X{
X	int	len;
X
X	if (m == 0)
X		return;
X	DotTo(m->m_line, m->m_char);
X	if (curchar > (len = length(curline)))
X		curchar = len;
X}
X
XMark *
XCurMark()
X{
X	if (curmark == 0)
X		complain("No mark.");
X	return curmark;
X}
X
XPtToMark()
X{
X	Line	*mline;
X	int	mchar;
X	Mark	*m = CurMark();
X
X	mline = curline;
X	mchar = curchar;
X
X	ToMark(m);
X	MarkSet(m, mline, mchar);
X}
X
X/* Fix marks for after a deletion.  For now, even marks that don't
X   float will actually float, because we can't allow marks to point
X   to non-existant lines. */
X
XDFixMarks(line1, char1, line2, char2)
Xregister Line	*line1,
X		*line2;
X{
X	register Mark	*m;
X	Line	*lp = line1;
X
X	if (curbuf->b_marks == 0)
X		return;
X	while (lp != line2->l_next) {
X		for (m = curbuf->b_marks; m != 0; m = m->m_next) {
X/*			if (!m->m_floater)
X				continue; */
X			if (m->m_line == lp)
X				m->m_char |= (1 << 15);
X		}
X		lp = lp->l_next;
X	}
X	for (m = curbuf->b_marks; m; m = m->m_next) {
X/*		if (!m->m_floater)
X			continue; */
X		if ((m->m_char & (1 << 15)) == 0)
X			continue;	/* Not effected */
X		m->m_char &= ~(1 << 15);
X		if (m->m_line == line1 && m->m_char < char1)
X			continue;	/* This mark is not affected */
X		if (line1 == line2) {
X			if (m->m_char >= char1 && m->m_char <= char2)
X				m->m_char = char1;
X			else if (m->m_char > char2)
X				m->m_char -= (char2 - char1);
X			/* Same line move the mark backward */
X		} else if (m->m_line == line2) {
X			if (m->m_char > char2)
X				m->m_char = char1 + (m->m_char - char2);
X			else
X				m->m_char = char1;
X			m->m_line = line1;
X		} else {
X			m->m_char = char1;
X			m->m_line = line1;
X		}
X	}
X}
X
X/* Fix marks after an insertion.  Marks that don't float are ignored
X   on insertion, which means PtToMark has to be careful ... */
X
XIFixMarks(line1, char1, line2, char2)
Xregister Line	*line1,
X		*line2;
X{
X	register Mark	*m;
X
X	for (m = curbuf->b_marks; m != 0; m = m->m_next) {
X		if (!m->m_floater)
X			continue;
X		if (m->m_line == line1) {
X			if (m->m_char > char1) {
X				m->m_line = line2;
X				if (line1 == line2)
X					m->m_char += (char2 - char1);
X				else
X					m->m_char = char2 + (m->m_char - char1);
X			}
X		} 
X	}
X}
@//E*O*F marks.c//
if test 4197 -ne "`wc -c <'marks.c'`"; then
    echo shar: error transmitting "'marks.c'" '(should have been 4197 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'setmaps.c'" '(2200 characters)'
if test -f 'setmaps.c' ; then 
  echo shar: will not over-write existing file "'setmaps.c'"
else
sed 's/^X//' >setmaps.c <<'@//E*O*F setmaps.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X#define TXT_TO_C
X
X#include "funcdefs.c"
X#undef putchar	/* From jove.h via funcdefs.c, conflicts with STDIO */
X#undef putc
X#undef getc
X#undef EOF
X#undef FILE
X#undef BUFSIZ
X#include <stdio.h>
X
Xmatch(choices, what)
Xregister struct cmd	choices[];
Xregister char	*what;
X{
X	register int	len;
X	int	i,
X		found = 0,
X		save,
X		exactmatch = -1;
X
X	len = strlen(what);
X	for (i = 0; choices[i].Name != 0; i++) {
X		if (*what != *choices[i].Name)
X			continue;
X		if (strncmp(what, choices[i].Name, len) == 0)
X			return i;
X	}
X	return -1;
X}
X
Xchar *
XPPchar(c)
Xint	c;
X{
X	static char	str[10];
X	char	*cp = str;
X
X	if (c == '\033')
X		strcpy(cp, "ESC");
X	else if (c < ' ')
X		(void) sprintf(cp, "C-%c", c + '@');
X	else if (c == '\177')
X		strcpy(cp, "^?");
X	else
X		(void) sprintf(cp, "%c", c);
X	return cp;
X}
X
Xextract(into, from)
Xchar	*into,
X	*from;
X{
X	from += 2;	/* Past tab and first double quote. */
X	while ((*into = *from++) != '"')
X		into++;
X	*into = 0;
X}
X
Xmain()
X{
X	FILE	*ifile,
X		*of;
X	char	line[100],
X		comname[70];
X	int	comnum,
X		ch;
X
X	ifile = stdin;
X	of = stdout;
X	if (ifile == NULL || of == NULL) {
X		printf("Cannot read input or write output.\n");
X		exit(1);
X	}
X	while (fgets(line, sizeof line, ifile) != NULL) {
X		if (strncmp(line, "\t\"", 2) != 0) {
X			fprintf(of, line);
X			ch = 0;
X			continue;
X		}
X		extract(comname, line);
X		if (strcmp(comname, "unbound") == 0) 
X			comnum = 12345;
X		else {
X			comnum = match(commands, comname);
X			if (comnum < 0) {
X				fprintf(stderr, "Cannot find command \"%s\".\n", comname);
X				exit(1);
X			}
X		}
X		if (comnum == 12345)
X			fprintf(of, "	(data_obj *) 0,                 /* %s */\n", PPchar(ch++));
X		else
X			fprintf(of, "	(data_obj *) &commands[%d],	/* %s */\n", comnum, PPchar(ch++));
X	}
X	fclose(of);
X	fclose(ifile);
X	exit(0);
X}
@//E*O*F setmaps.c//
if test 2200 -ne "`wc -c <'setmaps.c'`"; then
    echo shar: error transmitting "'setmaps.c'" '(should have been 2200 characters)'
fi
fi # end of overwriting check
echo shar: "End of archive 5 (of 13)."
cp /dev/null ark5isdone
DONE=true
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13; do
    if test -f ark${I}isdone; then
        echo "You have run archive ${I}."
    else
        echo "You still need to run archive ${I}."
        DONE=false
    fi
done
case $DONE in
    true)
        echo "You have run all 13 archives."
        echo 'Now read the README and Makefile.'
        ;;
esac
##  End of shell archive.
exit 0



More information about the Mod.sources mailing list