2.9BSD/usr/contrib/jove/jove_main.c

Compare this file to the similar file:
Show the results in this format:

/*
   Jonathan Payne at Lincoln-Sudbury Regional High School 4-19-83

   jove_main.c

   Contains the main loop, initializations, getch routine... */

#include "jove.h"

#include "termcap.h"

#include <sys/ioctl.h>
#include <signal.h>
#include <sgtty.h>

#ifdef TIOCSLTC
struct ltchars	ls1,
		ls2;
#endif

struct tchars	tc1,
		tc2;

int	errormsg;

int	iniargc;
char	**iniargv;

extern char	*tfname;

finish(code)
{
	int	Crashit = code && (code != LOGOEXIT);

#ifdef LSRHS_KLUDGERY
	if (Crashit)
		setdump(1);
#endif
	if (code == SIGINT) {
		char	c;

#ifndef SIGTSTP			/* Job stopping in other words */
		ignorf(signal(code, finish));
#endif
		message("Quit? ");
		UpdateMesg();
		ignore(read(0, &c, 1));
		message("");
		if ((c & 0377) != 'y') {
			redisplay();
			return;
		}
	}
	if (Crashit) {
		if (!Crashing) {
			putstr("Writing modified JOVE buffers...");
			Crashing++;
			exp_p = 0;
			WtModBuf();
		} else
			putstr("Complete lossage!");
	}
	ttyset(0);
	if (VE)
		putpad(VE, 1);
	Placur(LI - 1, 0);
	putpad(CE, 1);
	flusho();
#ifdef LSRHS_KLUDGERY
	if (VT)
		deal_with_scroll();
#endif
	ignore(unlink(tfname));
	if (Crashit)
		abort();
	exit(code);
}

#define NTOBUF	20		/* Should never get that far ahead */
static char	smbuf[NTOBUF],
		*bp = smbuf;
static int	nchars = 0;

Ungetc(c)
int	c;
{
	if (c == EOF || nchars >= NTOBUF)
		return EOF;
	*--bp = c;
	nchars++;
	return c;
}

getchar()
{
	if (nchars == 0) {
		if ((nchars = read(Input, smbuf, sizeof smbuf)) == 0) {
			if (Input)
				return EOF;
			finish(0);
		}
		bp = smbuf;
		InputPending = nchars > 1;
	}
	nchars--;
	return *bp++;
}

/* Returns non-zero if a character waiting */

charp()
{
	if (Input)
		return 0;
	if (nchars)		/* Quick check */
		return 1;

	else {
#ifdef FIONREAD
		long	c;

		if (ioctl(0, FIONREAD, (char *) &c) == -1)
#else
		int	c;

		if (ioctl(0, TIOCEMPTY, (char *) &c) == -1)
#endif
			c = 0;
		return (c > 0);
	}
}

ResetTerm()
{
	if (IS)
		putpad(IS, 1);
	if (VS)
		putpad(VS, 1);
	ttyset(1);
}

UnsetTerm()
{
	ttyset(0);
	if (VE)
		putpad(VE, 1);
	Placur(LI - 1, 0);
	outchar('\n');
	flusho();
}

PauseJove()
{
	UnsetTerm();
#ifdef SIGTSTP
	ignore(kill(0, SIGTSTP));
#else
	Suspend();
#endif
	ResetTerm();
	ClAndRedraw();
}

#ifndef SIGTSTP
Suspend()
{
	char	*shell,
		*getenv();
	int	pid;

	switch (pid = fork()) {
	case -1:
		complain("Fork failed");

	case 0:
		signal(SIGTERM, SIG_DFL);
		signal(SIGINT, SIG_DFL);
		execl(shell ? shell : "/bin/csh", "ed_shell", 0);
		message("Execl failed");
		_exit(1);

	default:
		signal(SIGQUIT, SIG_IGN);
		while (wait(0) != pid)
			;
		signal(SIGQUIT, finish);
	}
}
#endif

int	OKXonXoff = 0;		/* ^S and ^Q initially DON'T work */

ReInitTTY()
{
	ttyset(0);	/* Back to original settings */
	ttinit();
}

ttinit()
{
#ifdef TIOCSLTC
	ioctl(0, TIOCGLTC, (char *) &ls1);
	ls2 = ls1;
	ls2.t_suspc = (char) -1;
	ls2.t_dsuspc = (char) -1;
	ls2.t_flushc = (char) -1;
	ls2.t_lnextc = (char) -1;
#endif

	/* Change interupt and quit. */
	ioctl(0, TIOCGETC, (char *) &tc1);
	tc2 = tc1;
	tc2.t_intrc = '\035';
	tc2.t_quitc = (char) -1;
	if (OKXonXoff) {
		tc2.t_stopc = (char) -1;
		tc2.t_startc = (char) -1;
	}
	ttyset(1);

	/* Go into cbreak, and -echo and -CRMOD */

#ifdef SIGTSTP			/* New signal mechanism */
	ignorf(sigset(SIGHUP, finish));
	ignorf(sigset(SIGINT, finish));
	ignorf(sigset(SIGQUIT, SIG_IGN));
	ignorf(sigset(SIGBUS, finish));
	ignorf(sigset(SIGSEGV, finish));
	ignorf(sigset(SIGPIPE, finish));
	ignorf(sigset(SIGTERM, SIG_IGN));
#else
	ignorf(signal(SIGHUP, finish));
	ignorf(signal(SIGINT, finish));
	ignorf(signal(SIGQUIT, SIG_IGN));
	ignorf(signal(SIGBUS, finish));
	ignorf(signal(SIGSEGV, finish));
	ignorf(signal(SIGPIPE, finish));
	ignorf(signal(SIGTERM, SIG_IGN));
#endif
}

ttyset(n)
{
	struct sgttyb	tty;

	if (ioctl(0, TIOCGETP, (char *) &tty) == -1) {
		putstr("No terminal");
		exit(1);
	}
	if (n) {
		tty.sg_flags &= ~(ECHO | CRMOD);
		tty.sg_flags |= CBREAK;
	} else {
		tty.sg_flags |= (ECHO | CRMOD);
		tty.sg_flags &= ~CBREAK;
	}
	if (ioctl(0, TIOCSETN, (char *) &tty) == -1) {
		putstr("cbreak?");
		exit(1);
	}
	ioctl(0, TIOCSETC, n == 0 ? (char *) &tc1 : (char *) &tc2);
#ifdef TIOCSLTC
	ioctl(0, TIOCSLTC, n == 0 ? (char *) &ls1 : (char *) &ls2);
#endif
}

#ifdef LSRHS_KLUDGERY
deal_with_scroll()
{
	char	*pp;

	pp = getenv("SCROLL");
	if (!pp || !strcmp(pp, "smooth"))
		putstr("\033[?4h");	/* Put in smooth scroll. */
}
#endif

/* NOSTRICT */

char *
emalloc(size)
{
	char	*ptr;

	if (ptr = malloc((unsigned) size))
		return ptr;
	GCchunks();
	if (ptr = malloc((unsigned) size))
		return ptr;
	error("out of memory");
	/* NOTREACHED */
}

dispatch(c)
register int	c;
{
	struct function	*fp;

	fp = mainmap[c];
	if (fp == 0) {
		rbell();
		exp = 1;
		exp_p = errormsg = 0;
		message("");
		return;
	}
	ExecFunc(fp, 0
);
}

int	LastKeyStruck;

getch()
{
	int	c;

	if (stackp >= 0 && macstack[stackp]->Flags & EXECUTE)
		c = MacGetc();
	else {
		redisplay();
		if ((c = getchar()) == EOF)
			finish(SIGHUP);
		c &= 0177;
		if (KeyMacro.Flags & DEFINE)
			MacPutc(c);
	}
	LastKeyStruck = c;
	return c;
}

parse(argc, argv)
char	*argv[];
{
	BUFFER	*firstbuf = 0;
	char	c;

	message("Jonathan's Own Version of Emacs");

	*argv = (char *) 0;
	argvp = argv + 1;

	while (argc > 1) {
		if (argv[1][0] == '-') {
			if (argv[1][1] == 't') {
				++argv;
				--argc;
				exp_p = 1;
				find_tag(argv[1]);
				if (!firstbuf)
					firstbuf = curbuf;
			}
		} else if (argv[1][0] == '+' &&
					(c = argv[1][1]) >= '0' && c <= '9') {
			++argv;
			--argc;
			SetBuf(do_find(curwind, argv[1]));
			if (!firstbuf)
				firstbuf = curbuf;
			SetLine(next_line(curline, atoi(&argv[0][1]) - 1));
		} else {
			SetBuf(do_find(curwind, argv[1]));
			if (!firstbuf)
				firstbuf = curbuf;
		}

		++argv;
		--argc;
	}

	if (firstbuf)
		SetBuf(firstbuf);
}

copy_n(f, t, n)
register int	*f,
		*t,
		n;
{
	while (n--)
		*f++ = *t++;
}

#ifdef lint
Ignore(a)
	char *a;
{

	a = a;
}

Ignorf(a)
	int (*a)();
{

	a = a;
}
#endif

/* VARARGS1 */

error(fmt, args)
char	*fmt;
{
	if (fmt) {
		format(mesgbuf, fmt, &args);
		UpdMesg++;
	}
	rbell();
	longjmp(mainjmp, ERROR);
}

/* VARARGS1 */

complain(fmt, args)
char	*fmt;
{
	if (fmt) {
		format(mesgbuf, fmt, &args);
		UpdMesg++;
	}
	rbell();	/* Always ring the bell now */
	longjmp(mainjmp, COMPLAIN);
}

/* VARARGS1 */

confirm(fmt, args)
char	*fmt;
{
	char *yorn;

	format(mesgbuf, fmt, &args);
	yorn = ask((char *)0, mesgbuf);
	if (*yorn != 'Y' && *yorn != 'y')
		longjmp(mainjmp, COMPLAIN);
}

#ifndef PROFILE
exit(status)
{
	flusho();
	_exit(status);
}
#endif

Recurse()
{
	RecDepth++;
	DoKeys(0);
	RecDepth--;
}

read_ch()
{
	int	c;

	if ((c = peekc) != -1) {
		peekc = -1;
		return c;
	}
	return getch();
}

DoKeys(first)
{
	int	c;
	jmp_buf	savejmp;

	copynchar((char *) savejmp, (char *) mainjmp, sizeof savejmp);

	switch (setjmp(mainjmp)) {
	case 0:
		if (first)
			parse(iniargc, iniargv);
		break;

	case QUIT:
		copynchar((char *) mainjmp, (char *) savejmp, sizeof mainjmp);
		return;

	case ERROR:
		getDOT();	/* God knows what state linebuf was in */

	case COMPLAIN:
		IOclose();
		Getchar = getch;
		if (Input) {
			ignore(close(Input));
			Input = 0;	/* Terminal has control now */
		}
		errormsg++;
		FixMacros();
		Asking = 0;		/* Not anymore we ain't */
		redisplay();
		break;
	}

	this_cmd = last_cmd = 0;

	for (;;) {
		exp = 1;
		exp_p = 0;
		last_cmd = this_cmd;
cont:
		this_cmd = 0;
		c = read_ch();
		if (c == -1)
			continue;
	 	dispatch(c);
		if (this_cmd == ARG_CMD)
			goto cont;
	}
}

int	Crashing = 0;

main(argc, argv)
char	*argv[];
{
	extern char searchbuf[];
	char	*home;

	peekc = -1;
	killptr = errormsg = 0;
	curbuf = world = (BUFFER *) 0;

	iniargc = argc;
	iniargv = argv;

	searchbuf[0] = '\0';
	InputPending = 0;
	Asking = 0;
	Crashing = 0;
	Input = 0;		/* Terminal? */
	RecDepth = 0;		/* Top level */
	Getchar = getch;

	if (setjmp(mainjmp)) {
		printf("Pre-error: \"%s\"; tell Jon Payne\n", mesgbuf);
		finish(0);
	}

	getTERM();
	InitCM();
	CanScroll = ((AL && DL) || VT);
	settout();
	make_scr();	/* Do this before making zero */
	tmpinit();	/* Init temp file */
	MacInit();	/* Initialize Macros */
	InitFuncs();	/* Initialize functions and variables */
	InitBindings();	/* Everyday EMACS commands */
	winit();	/* Initialize window */

	noflags(origflags);
	curbuf = do_select(curwind, Mainbuf);

	if (home = getenv("HOME"))
		ignore(joverc(sprint("%s/.joverc", home)));
	ttinit();	/* Initialize terminal (after ~/.joverc) */

	putpad(CL, 1);
	if (IS)
		putpad(IS, 1);
	if (VS)
		putpad(VS, 1);

	copy_n(origflags, curbuf->b_flags, NFLAGS);
	/* All new buffers will have these flags when created. */
	RedrawDisplay();	/* Start the redisplay process */
	DoKeys(1);
	finish(0);
}