home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- * is provided to you without charge, and with no warranty. You may give *
- * away copies of JOVE, including sources, provided that this notice is *
- * included in all the files. *
- ***************************************************************************/
-
- /* Contains the main loop initializations, and some system dependent
- type things, e.g. putting terminal in CBREAK mode, etc. */
-
- #include "jove.h"
- #include "fp.h"
- #include "termcap.h"
- #include "ctype.h"
- #include "chars.h"
- #include "disp.h"
- #include "re.h" /* for find_tag() */
- #include "rec.h"
- #if defined(IPROCS)
- # include "iproc.h"
- #endif
-
- #ifdef MAC
- # include "mac.h"
- #else
- # ifdef STDARGS
- # include <stdarg.h>
- # else
- # include <varargs.h>
- # endif
- # include <sys/stat.h>
- #endif
-
- #include <signal.h>
- #include <errno.h>
-
- #ifdef UNIX
- # ifndef SYSV
- # include <sgtty.h>
- # else
- # include <termio.h>
- # endif /* SYSV */
- #endif /* UNIX */
-
- #ifdef MSDOS
- # include <process.h>
- #endif /* MSDOS */
-
- #ifndef MAC
- # include <fcntl.h>
- #endif
-
- #ifdef MSDOS
- extern time_t time proto((time_t *));
- private void break_off proto((void)),
- break_rst proto((void));
- #endif
-
- private void
- DoKeys proto((int firsttime)),
- UNIX_cmdline proto((int argc,char * *argv));
-
- #ifdef MSDOS
- extern void UnsetTerm proto((char *));
- #else
- private void UnsetTerm proto((char *));
- #endif
-
- /* Various tty state structures.
- * Each is an array, subscripted by one of "OFF" or "ON".
- */
-
- #ifndef MAC
- #include "ttystate.h"
- #endif
-
- #ifdef UNIX
- # ifdef TIOCSLTC
- struct ltchars ls[2];
- # endif /* TIOCSLTC */
-
- # if defined(TIOCGETC) && !defined(SYSV)
- struct tchars tc[2];
- # endif
-
- # ifdef PASS8 /* use pass8 instead of raw for meta-key */
- private int lmword[2]; /* local mode word */
- # endif
-
- # ifdef BRLUNIX
- struct sg_brl sg[2];
- # else
- # ifdef SYSV
- struct termio sg[2];
- # else /* SYSV */
- struct sgttyb sg[2];
- # endif /* SYSV */
- # endif /* BRLUNIX */
-
- # ifdef BIFF
- private struct stat tt_stat; /* for biff */
- # ifndef BSD4_2
- private char *tt_name = 0; /* name of the control tty */
- extern char *ttyname(); /* for systems w/o fchmod ... */
- # endif
- private int dw_biff = NO; /* whether or not to fotz at all */
- # endif /* BIFF */
- #endif /* UNIX */
-
- int errormsg;
- char NullStr[] = "";
- jmp_buf mainjmp;
-
-
- #ifdef MSDOS
- # define SIGHUP 99
- #endif /* MSDOS */
-
- /* finish() does not return, so it is funny that it returns a non-void
- * result. This is because most systems claim that signal(2) deals
- * with functions of type int (). ANSI changes this: the function
- * type must be void (int). This bridge must soon be crossed.
- */
- SIGRESULT
- finish(code)
- int code;
- {
- int CoreDump = (code != 0 && code != SIGHUP),
- DelTmps = 1; /* Usually we delete them. */
-
- if (code == SIGINT) {
- char c;
- #if defined(IPROCS) && defined(PIPEPROCS)
- int started;
- #endif
- #ifndef MENLO_JCL
- (void) signal(code, finish);
- #endif
- f_mess("Abort (Type 'n' if you're not sure)? ");
- #ifndef MSDOS
- # if defined(IPROCS) && defined(PIPEPROCS)
- started = kbd_stop();
- # endif
- #ifdef SYSV
- if (read(0, &c, (size_t) 1) != 1)
- #endif
- (void) read(0, &c, (size_t) 1);
- # if defined(IPROCS) && defined(PIPEPROCS)
- if (started)
- (void) kbd_strt();
- # endif
- #else /* MSDOS */
- c = getrawinchar();
- #endif /* MSDOS */
- message(NullStr);
- if ((c & 0377) != 'y') {
- redisplay();
- SIGRETURN;
- }
- }
- DisabledRedisplay = YES;
- #ifndef MAC
- UnsetTerm(NullStr);
- #endif
- #if defined(IPROCS) && defined(PIPEPROCS)
- kbd_kill(); /* kill the keyboard process */
- #endif
- #ifndef MSDOS
- if (code != 0) {
- if (!Crashing) {
- Crashing = YES;
- lsave();
- SyncRec();
- writef("JOVE CRASH!! (code %d)\n", code);
- if (ModBufs(1)) {
- writef("Your buffers have been saved.\n");
- writef("Use \"jove -r\" to have a look at them.\n");
- DelTmps = 0; /* Don't delete anymore. */
- } else
- writef("You didn't lose any work.\n");
- } else
- writef("\r\nYou may have lost your work!\n");
- }
- #endif /* MSDOS */
- flusho();
- if (DelTmps) {
- #if defined(IPROCS) && !defined(PIPEPROCS)
- (void) signal(SIGCHLD, SIG_IGN);
- #endif
- tmpclose();
- #ifndef MSDOS
- recclose();
- #endif /* MSDOS */
- }
- #ifdef UNIX
- if (CoreDump)
- abort();
- #ifdef PROFILING
- exit(0);
- #else
- _exit(0);
- #endif
- #else /* MSDOS or MAC*/
- #ifdef MSDOS
- break_rst(); /* restore previous ctrl-c handling */
- #endif
- exit(0);
- #endif /* UNIX */
- /*NOTREACHED*/
- }
-
- private char smbuf[20],
- *bp = smbuf;
- private int nchars = 0;
-
- private char peekbuf[10],
- *peekp = peekbuf;
-
- #if defined(SYSV) || defined(M_XENIX)
- void
- setblock(fd, on) /* turn blocking on or off */
- register int fd, on;
- {
- static int blockf, nonblockf;
- static int first = 1;
- int flags;
-
- if (first) {
- first = 0;
- if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
- finish(SIGHUP);
- blockf = flags & ~O_NDELAY; /* make sure O_NDELAY is off */
- nonblockf = flags | O_NDELAY; /* make sure O_NDELAY is on */
- }
- if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
- finish(SIGHUP);
- }
- #endif /* SYSV */
-
- private int
- Peekc()
- {
- int c;
-
- if (peekp == peekbuf)
- c = EOF;
- else
- c = *--peekp & 0377;
- return c;
- }
-
- void
- Ungetc(c)
- int c;
- {
- if (peekp == &peekbuf[(sizeof peekbuf) - 1])
- return; /* Sorry, can't oblige you ... */
- *peekp++ = c;
- }
-
- int InputPending = 0;
-
- char *Inputp = 0;
-
- #if (defined(IPROCS) && !defined(PIPEPROCS)) /* that is, if ptys */
- int
- jgetchar()
- {
- long reads;
- register int tmp,
- nfds;
- int c;
-
- if (nchars <= 0) {
- /* Get a character from the keyboard, first checking for
- any input from a process. Handle that first, and then
- deal with the terminal input. */
- do {
- do {
- reads = global_fd;
- nfds = select(32, &reads, (long *) 0, (long *) 0, (struct timeval *) 0);
- } while (nfds < 0 && errno == EINTR);
-
- if (nfds == -1)
- complain("\rerror %d in select %ld", errno, global_fd);
- else {
- if (reads & 01) {
- nchars = read(0, smbuf, sizeof(smbuf));
- reads &= ~01;
- nfds -= 1;
- }
- while (nfds--) {
- tmp = ffs(reads) - 1;
- read_proc(tmp);
- reads &= ~(1L << tmp);
- }
- }
- } while (nchars <= 0);
-
- if (nchars <= 0)
- finish(SIGHUP);
-
- bp = smbuf;
- InputPending = (nchars > 1);
- }
-
- if (((c = *bp) & 0200) && MetaKey != 0) {
- *bp = (c & CHARMASK);
- return '\033';
- }
- nchars -= 1;
- return *bp++ & 0377;
- }
-
- #else
-
- jgetchar()
- {
- register int c;
- struct header {
- int pid;
- int nbytes;
- } header;
- int n;
-
- normal:
- if (nchars <= 0) {
- bp = smbuf;
- #ifdef MSDOS
- *bp = getrawinchar();
- nchars = 1;
- #else
- # ifdef IPROCS
- if (NumProcs == 0) {
- # endif
- do
- nchars = read(0, smbuf, sizeof smbuf);
- # ifdef SYSV
- while (nchars == 0 || (nchars < 0 && errno == EINTR));
- if (nchars < 0)
- # else
- while (nchars < 0 && errno == EINTR);
- if (nchars <= 0)
- # endif /* SYSV */
- finish(SIGHUP);
- # ifdef IPROCS
- } else for (;;) {
- n = f_readn(ProcInput, &header, sizeof (header));
- if (n == EOF) {
- printf("\rError reading kbd process.\n");
- finish(1);
- }
- /* data is from the keyboard process */
- if (header.pid == kbd_pid) {
- nchars = f_readn(ProcInput, smbuf, header.nbytes);
- if (nchars != header.nbytes) {
- printf("\rError reading kbd process.");
- finish(1);
- } else
- break;
- } else
- read_proc(header.pid, header.nbytes);
- if (NumProcs == 0) {
- (void) kbd_stop();
- goto normal;
- }
- }
- # endif /* IPROCS */
- #endif /* MSDOS */
- InputPending = nchars > 0;
- }
- if (((c = *bp) & 0200) && MetaKey != 0) {
- *bp = (c & CHARMASK);
- return '\033';
- }
- nchars -= 1;
- return (*bp++ & CHARMASK);
- }
-
- #endif /* IPROCS */
-
- /* Returns non-zero if a character waiting */
-
- int
- charp()
- {
- int some = 0;
-
- if (InJoverc != 0 || nchars > 0 || Inputp != 0)
- return 1;
- #ifdef BRLUNIX
- {
- static struct sg_brl gttyBuf;
-
- gtty(0, (char *) >tyBuf);
- if (gttyBuf.sg_xflags & INWAIT)
- some += 1;
- }
- #endif
- #ifdef FIONREAD
- {
- long c;
-
- if (ioctl(0, FIONREAD, (UnivPtr) &c) == -1)
- c = 0;
- some = (c > 0);
- }
- #endif /* FIONREAD */
- #if defined(SYSV) || defined(M_XENIX)
- setblock(0, 0); /* turn blocking off */
- nchars = read(0, smbuf, sizeof smbuf); /* Is anything there? */
- setblock(0, 1); /* turn blocking on */
- if (nchars > 0) /* something was there */
- bp = smbuf; /* make sure bp points to it */
- some = (nchars > 0); /* just say we found something */
- #endif /* SYSV */
- #ifdef c70
- some = !empty(0);
- #endif
- #ifdef MSDOS
- some = rawkey_ready();
- #endif
- #ifdef MAC
- some = rawchkc();
- #endif
- return some;
- }
-
- void do_sgtty proto((void));
- #ifdef BIFF
- private void biff_init proto((void));
- #endif
-
- #ifdef TERMCAP
-
- private void
- ResetTerm()
- {
- do_sgtty(); /* this is so if you change baudrate or stuff
- like that, JOVE will notice. */
- ttyset(ON);
- putpad(TI, 1);
- putpad(VS, 1);
- putpad(KS, 1);
- #ifdef UNIX
- (void) chkmail(YES); /* force it to check to we can be accurate */
- #endif
- #ifdef BIFF
- if (BiffChk != dw_biff)
- biff_init();
- /* just in case we changed our minds about whether to deal with
- biff */
- #endif
- }
-
- private void
- UnsetTerm(mesg)
- char *mesg;
- {
- ttyset(OFF);
- #ifdef ID_CHAR
- INSmode(0);
- #endif
- putpad(KE, 1);
- putpad(VE, 1);
- /*
- * For terminals without an alternate page, go the bottom of the
- * screen. Alternate page - just return to the original place on
- * the screen
- */
- if (!TE) {
- Placur(ILI, 0);
- putpad(CE, 1);
- } else {
- putpad(TE, 1);
- }
- if (mesg[0] != '\0')
- writef("%s\n", mesg);
- flusho();
- }
- #endif /* TERMCAP */
-
- #ifdef JOB_CONTROL
- void
- PauseJove()
- {
- UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
- (void) kill(0, SIGTSTP);
- ResetTerm();
- ClAndRedraw();
- }
- #endif
-
-
- #ifndef MAC
- void
- Push()
- {
- #ifndef MSDOS
- int pid;
- SIGRESULT (*old_quit) proto((int)) = signal(SIGQUIT, SIG_IGN);
- #endif /* MSDOS */
- SIGRESULT (*old_int) proto((int)) = signal(SIGINT, SIG_IGN);
-
- #ifndef MSDOS
- #ifdef IPROCS
- SigHold(SIGCHLD);
- #endif
- #if defined(TIOCGWINSZ) && defined(SIGWINCH) && defined(SigRelse)
- SigHold(SIGWINCH);
- #endif
- alarm(0);
- switch (pid = fork()) {
- case -1:
- complain("[Fork failed]");
- /*NOTREACHED*/
-
- case 0:
- UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
- #if defined(TIOCGWINSZ) && defined(SIGWINCH) && defined(SigRelse)
- SigRelse(SIGWINCH);
- #endif
- #ifdef IPROCS
- SigRelse(SIGCHLD);
- #endif
- (void) signal(SIGTERM, SIG_DFL);
- #else /* MSDOS */
- UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
- #endif /* MSDOS */
- (void) signal(SIGINT, SIG_DFL);
- #ifdef UNIX
- (void) signal(SIGQUIT, SIG_DFL);
- execl(Shell, basename(Shell), "-i", (char *)0);
- message("[Execl failed]");
- _exit(1);
- }
- #ifdef IPROCS
- SigRelse(SIGCHLD);
- #endif
- dowait(pid, (int *) 0);
- #endif /* UNIX */
- #ifdef MSDOS
- break_rst();
- if (spawnl(0, Shell, basename(Shell), (char *)0) == -1)
- message("[Spawn failed]");
- #endif /* MSDOS */
- #ifndef MAC
- ResetTerm();
- #endif
- #if defined(TIOCGWINSZ) && defined(SIGWINCH) && defined(SigRelse)
- SigRelse(SIGWINCH);
- #endif
- ClAndRedraw();
- #ifndef MSDOS
- (void) signal(SIGQUIT, old_quit);
- #else /* MSDOS */
- break_off();
- getCWD();
- #endif /* MSDOS */
- (void) signal(SIGINT, old_int);
- #ifndef MSDOS
- (void) alarm((unsigned) (UpdFreq - (time((time_t *) 0) % UpdFreq)));
- #endif
- }
- #endif /* MAC */
-
- int OKXonXoff = 0, /* ^S and ^Q initially DON'T work */
- IntChar = CTL(']');
-
- private void
- ttsize()
- {
- #ifdef UNIX
- # ifdef TIOCGWINSZ
- struct winsize win;
-
- if (ioctl (0, TIOCGWINSZ, (UnivPtr) &win) == 0) {
- if (win.ws_col)
- CO = win.ws_col;
- if (win.ws_row)
- LI = win.ws_row;
- }
- # else /* TIOCGWINSZ */
- # ifdef BTL_BLIT
- #include <sys/jioctl.h>
- struct jwinsize jwin;
-
- if (ioctl(0, JWINSIZE, &jwin) == 0) {
- if (jwin.bytesx)
- CO = jwin.bytesx;
- if (jwin.bytesy)
- LI = jwin.bytesy;
- }
- # endif /* BTL_BLIT */
- # endif /* TIOCGWINSZ */
- #endif /* UNIX */
- #ifdef MAC
- CO = getCO(); /* see mac.c */
- LI = getLI();
- Windchange = 1;
- clr_page();
- #endif
- ILI = LI - 1;
- }
-
- #ifdef BIFF
- private void
- biff_init()
- {
- dw_biff = ((BiffChk) &&
- # ifndef BSD4_2
- ((tt_name != 0) || (tt_name = ttyname(0))) &&
- (stat(tt_name, &tt_stat) != -1) &&
- # else
- (fstat(0, &tt_stat) != -1) &&
- # endif
- (tt_stat.st_mode & S_IEXEC)); /* he's using biff */
-
- }
-
- private void
- biff(on)
- int on;
- {
- if (dw_biff == NO)
- return;
- # ifndef BSD4_2
- (void) chmod(tt_name, on ? tt_stat.st_mode :
- (tt_stat.st_mode & ~S_IEXEC));
- # else
- (void) fchmod(0, on ? tt_stat.st_mode :
- (tt_stat.st_mode & ~S_IEXEC));
- # endif
- }
-
- #endif /* BIFF */
-
- private void
- ttinit()
- {
- #ifdef BIFF
- biff_init();
- #endif
- #ifdef TIOCSLTC
- (void) ioctl(0, TIOCGLTC, (UnivPtr) &ls[OFF]);
- ls[ON] = ls[OFF];
- ls[ON].t_suspc = (char) -1;
- ls[ON].t_dsuspc = (char) -1;
- ls[ON].t_flushc = (char) -1;
- ls[ON].t_lnextc = (char) -1;
- #endif
-
- #if defined(TIOCGETC) && !defined(SYSV)
- /* Change interupt and quit. */
- (void) ioctl(0, TIOCGETC, (UnivPtr) &tc[OFF]);
- tc[ON] = tc[OFF];
- tc[ON].t_intrc = IntChar;
- tc[ON].t_quitc = (char) -1;
- if (OKXonXoff) {
- tc[ON].t_stopc = (char) -1;
- tc[ON].t_startc = (char) -1;
- }
- #endif /* TIOCGETC */
- do_sgtty();
- }
-
- private int done_ttinit = 0;
-
- void
- do_sgtty()
- {
- #ifdef UNIX
- # ifdef SYSV
- (void) ioctl(0, TCGETA, (char *) &sg[OFF]);
- # else
- (void) gtty(0, &sg[OFF]);
- # endif /* SYSV */
- sg[ON] = sg[OFF];
-
- # ifdef LPASS8
- (void) ioctl(0, TIOCLGET, (UnivPtr) &lmword[OFF]);
- lmword[ON] = lmword[OFF];
- if (MetaKey == YES)
- lmword[ON] |= LPASS8;
- if (HZ)
- lmword[ON] &= ~LTILDE;
- # endif
-
- # ifdef SYSV
- TABS = !((sg[OFF].c_oflag & TAB3) == TAB3);
- ospeed = sg[OFF].c_cflag & CBAUD;
-
- if (OKXonXoff)
- sg[ON].c_iflag &= ~(IXON | IXOFF);
- sg[ON].c_iflag &= ~(INLCR|ICRNL|IGNCR);
- sg[ON].c_lflag &= ~(ICANON|ECHO);
- sg[ON].c_oflag &= ~(OCRNL|ONLCR);
- sg[ON].c_cc[VINTR] = IntChar;
- sg[ON].c_cc[VQUIT] = (char) -1;
- sg[ON].c_cc[VMIN] = sizeof smbuf;
- sg[ON].c_cc[VTIME] = 1;
- # else
- TABS = !(sg[OFF].sg_flags & XTABS);
- sg[ON].sg_flags &= ~XTABS;
- ospeed = sg[OFF].sg_ospeed;
- # ifdef BRLUNIX
- sg[ON].sg_flags &= ~(ECHO | CRMOD);
- sg[ON].sg_flags |= CBREAK;
-
- /* VT100 Kludge: leave STALL on for flow control if DC3DC1 (Yuck.) */
- sg[ON].sg_xflags &= ~((sg[ON].sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
- # else
- sg[ON].sg_flags &= ~(ECHO | CRMOD);
- # endif /* BRLUNIX */
-
- # ifdef LPASS8
- sg[ON].sg_flags |= CBREAK;
- # else
- sg[ON].sg_flags |= (MetaKey ? RAW : CBREAK);
- # endif
- # endif /* SYSV */
- #endif /* UNIX */
-
- #ifdef MSDOS
- # ifndef IBMPC
- setmode(1, 0x8000);
- # endif /* IBMPC */
- TABS = 0;
- #endif /* MSDOS */
- }
-
- void
- tty_reset()
- {
- if (!done_ttinit)
- return;
- ttyset(OFF); /* go back to original modes */
- ttinit();
- ttyset(ON);
- }
-
- /* If n is OFF reset to original modes */
-
- void
- ttyset(n)
- int n;
- {
- if (!done_ttinit && n == 0) /* Try to reset before we've set! */
- return;
- #ifdef UNIX
- # ifdef SYSV
- (void) ioctl(0, TCSETAW, (UnivPtr) &sg[n]);
- # else
- # ifdef BRLUNIX
- (void) stty(0, &sg[n]);
- # else
- (void) ioctl(0, TIOCSETN, (UnivPtr) &sg[n]);
- # endif /* BRLUNIX */
- # endif /* SYSV */
-
- # if defined(TIOCSETC) && !defined(SYSV)
- (void) ioctl(0, TIOCSETC, (UnivPtr) &tc[n]);
- # endif /* TIOCSETC */
- # ifdef TIOCSLTC
- (void) ioctl(0, TIOCSLTC, (UnivPtr) &ls[n]);
- # endif /* TIOCSLTC */
- # ifdef LPASS8
- (void) ioctl(0, TIOCLSET, (UnivPtr) &lmword[n]);
- # endif
- #endif /* UNIX */
-
- #ifdef MSDOS
- # ifndef IBMPC
- setmode(1, n == 0 ? 0x4000 : 0x8000);
- # endif
- #endif /* MSDOS */
- done_ttinit = 1;
- #ifdef BIFF
- biff(!n);
- #endif
- }
-
- int this_cmd,
- last_cmd,
- LastKeyStruck,
- MetaKey = 0;
-
- int
- getch()
- {
- register int c,
- peekc;
-
- if (Inputp) {
- if ((c = *Inputp++) != '\0')
- return LastKeyStruck = c;
- Inputp = NULL;
- }
-
- if (InJoverc)
- return EOF; /* somethings wrong if Inputp runs out while
- we're reading a .joverc file. */
-
- #ifndef MSDOS
- if (ModCount >= SyncFreq) {
- ModCount = 0;
- SyncRec();
- }
- #endif /* MSDOS */
-
- /* If we're not interactive and we're not executing a macro,
- AND there are no ungetc'd characters, we read from the
- terminal (i.e., getch()). And characters only get put
- in macros from inside this if. */
- if (((peekc = c = Peekc()) == EOF) &&
- (Interactive || ((c = mac_getc()) == EOF))) {
- /* So messages that aren't error messages don't
- hang around forever. */
- if (!UpdMesg && !Asking && mesgbuf[0] != '\0' && !errormsg)
- message(NullStr);
- redisplay();
- #ifdef UNIX
- inIOread = 1;
- #endif
- if ((c = jgetchar()) == EOF)
- finish(SIGHUP);
- #ifdef UNIX
- inIOread = 0;
- #endif
-
- if (!Interactive && InMacDefine)
- mac_putc(c);
- }
- if (peekc == EOF) /* don't add_stroke peekc's */
- add_stroke(c);
- return LastKeyStruck = c;
- }
-
- #ifdef UNIX
- private void
- dorecover()
- {
- /* Since recover is a normal cooked mode program, reset the terminal */
- UnsetTerm(NullStr);
- #if defined(IPROCS) && defined(PIPEPROCS)
- kbd_kill(); /* kill the keyboard process */
- #endif
- execl(Recover, "recover", "-d", TmpFilePath, (char *) NULL);
- writef("%s: execl failed!\n", Recover);
- flusho();
- _exit(-1);
- /* NOTREACHED */
- }
- #endif /* UNIX */
-
- void
- ShowVersion()
- {
- s_mess("Jonathan's Own Version of Emacs (%s)", version);
- }
-
- private void
- UNIX_cmdline(argc, argv)
- int argc;
- char *argv[];
- {
- int lineno = 0,
- nwinds = 1;
- Buffer *b;
-
- ShowVersion();
- while (argc > 1) {
- if (argv[1][0] != '-' && argv[1][0] != '+') {
- int force = (nwinds > 0 || lineno != 0);
-
- #ifdef MSDOS
- strlwr(argv[1]);
- #endif
- minib_add(argv[1], force);
- b = do_find(nwinds > 0 ? curwind : (Window *) NULL,
- argv[1], force);
- if (force) {
- SetABuf(curbuf);
- SetBuf(b);
- if (lineno >= 0)
- SetLine(next_line(curbuf->b_first, lineno));
- else
- SetLine(curbuf->b_last);
- if (nwinds > 1)
- NextWindow();
- if (nwinds)
- nwinds -= 1;
- }
- lineno = 0;
- } else switch (argv[1][1]) {
- case 'd':
- argv += 1;
- argc -= 1;
- break;
-
- case 'j': /* Ignore .joverc in HOME */
- break;
- #ifndef MAC
- case 'p':
- argv += 1;
- argc -= 1;
- if (argv[1] != NULL) {
- SetBuf(do_find(curwind, argv[1], NO));
- ErrParse();
- nwinds = 0;
- }
- break;
- #endif
- case 't':
- /* check if syntax is -tTag or -t Tag */
- if (argv[1][2] != '\0') {
- find_tag(&(argv[1][2]), YES);
- } else {
- argv += 1;
- argc -= 1;
- if (argv[1] != NULL)
- find_tag(argv[1], YES);
- }
- break;
-
- case 'w':
- if (argv[1][2] == '\0')
- nwinds += 1;
- else {
- int n;
-
- (void) chr_to_int(&argv[1][2], 10, NO, &n);
- nwinds += -1 + n;
- }
- (void) div_wind(curwind, nwinds - 1);
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- (void) chr_to_int(&argv[1][1], 10, NO, &lineno);
- lineno -= 1;
- break;
- case 0:
- lineno = -1; /* goto end of file ... */
- break; /* just like some people's */
- } /* favourite editor */
- argv += 1;
- argc -= 1;
- }
- }
-
- #ifdef STDARGS
- void
- error(char *fmt, ...)
- #else
- /*VARARGS1*/ void
- error(fmt, va_alist)
- char *fmt;
- va_dcl
- #endif
- {
- va_list ap;
-
- if (fmt) {
- va_init(ap, fmt);
- format(mesgbuf, sizeof mesgbuf, fmt, ap);
- va_end(ap);
- UpdMesg = YES;
- }
- rbell();
- longjmp(mainjmp, ERROR);
- }
-
- #ifdef STDARGS
- void
- complain(char *fmt, ...)
- #else
- /*VARARGS1*/ void
- complain(fmt, va_alist)
- char *fmt;
- va_dcl
- #endif
- {
- va_list ap;
-
- if (fmt) {
- va_init(ap, fmt);
- format(mesgbuf, sizeof mesgbuf, fmt, ap);
- va_end(ap);
- UpdMesg = YES;
- }
- rbell();
- longjmp(mainjmp, COMPLAIN);
- }
-
- #ifdef STDARGS
- void
- confirm(char *fmt, ...)
- #else
- /*VARARGS1*/ void
- confirm(fmt, va_alist)
- char *fmt;
- va_dcl
- #endif
- {
- char *yorn;
- va_list ap;
-
- va_init(ap, fmt);
- format(mesgbuf, sizeof mesgbuf, fmt, ap);
- va_end(ap);
- yorn = ask((char *) 0, mesgbuf);
- if (*yorn != 'Y' && *yorn != 'y')
- longjmp(mainjmp, COMPLAIN);
- }
-
- int RecDepth = 0;
-
- void
- Recur()
- {
- char bname[128];
- Mark *m;
-
- swritef(bname, "%s", curbuf->b_name);
- m = MakeMark(curline, curchar, M_FLOATER);
-
- RecDepth += 1;
- UpdModLine = YES;
- DoKeys(NO); /* NO means not first time */
- UpdModLine = YES;
- RecDepth -= 1;
- SetBuf(do_select(curwind, bname));
- if (!is_an_arg())
- ToMark(m);
- DelMark(m);
- }
-
- #ifdef MAC
- jmp_buf auxjmp;
- #endif
-
- private int iniargc; /* main sets these for DoKeys() */
- private char **iniargv;
-
- private void
- DoKeys(firsttime)
- int firsttime;
- {
- int c;
- jmp_buf savejmp;
-
- push_env(savejmp);
-
- switch (setjmp(mainjmp)) {
- case 0:
- if (firsttime)
- UNIX_cmdline(iniargc, iniargv);
- break;
-
- case QUIT:
- if (RecDepth == 0) {
- if (ModMacs()) {
- rbell();
- if (CharUpcase(*ask("No",
- "Some MACROS haven't been saved; leave anyway? ")) != 'Y')
- break;
- }
- if (ModBufs(0)) {
- rbell();
- if (CharUpcase(*ask("No",
- "Some buffers haven't been saved; leave anyway? ")) != 'Y')
- break;
- }
- #ifdef IPROCS
- KillProcs();
- #endif
- }
- pop_env(savejmp);
- return;
-
- case ERROR:
- getDOT(); /* God knows what state linebuf was in */
- /*FALLTHROUGH*/
- case COMPLAIN:
- {
- gc_openfiles(); /* close any files we left open */
- errormsg = YES;
- unwind_macro_stack();
- Asking = 0;
- curwind->w_bufp = curbuf;
- DisabledRedisplay = NO;
- redisplay();
- break;
- }
- }
-
- this_cmd = last_cmd = 0;
-
- for (;;) {
- #ifdef MAC
- setjmp(auxjmp);
- #endif
- if (this_cmd != ARG_CMD) {
- clr_arg_value();
- last_cmd = this_cmd;
- init_strokes();
- }
- #ifdef MAC
- HiliteMenu(0);
- EventCmd = 0;
- menus_on();
- #endif
- c = getch();
- if (c == EOF)
- continue;
- dispatch(c);
- }
- }
-
- int Crashing = 0;
-
- private char **
- scanvec(args, str)
- register char **args,
- *str;
- {
- while (*args) {
- if (strcmp(*args, str) == 0)
- return args;
- args += 1;
- }
- return 0;
- }
-
- #ifdef UNIX
- int UpdFreq = 30,
- inIOread = 0;
-
- private SIGRESULT
- updmode(junk)
- int junk; /* passed in on signal; of no interest */
- {
- UpdModLine = YES;
- if (inIOread)
- redisplay();
- #ifndef JOB_CONTROL
- (void) signal(SIGALRM, updmode);
- #endif
- (void) alarm((unsigned) (UpdFreq - (time((time_t *) 0) % UpdFreq)));
- SIGRETURN;
- }
- #endif /* UNIX */
-
- #ifdef MSDOS
- # ifndef IBMPC
- char ttbuf[JBUFSIZ];
- # endif /* IBMPC */
- #endif /* MSDOS */
-
- #if defined(MAC) || (defined(TIOCGWINSZ) && defined(SIGWINCH))
- #ifndef MAC
- private
- #endif
- SIGRESULT
- win_reshape(junk)
- int junk; /* passed in when invoked by a signal; of no interest */
- {
- register int oldLI;
- register int newsize, total;
- register Window *wp;
-
- #ifdef UNIX
- (void) SigHold(SIGWINCH);
- #endif
- /*
- * Save old number of lines.
- */
- oldLI = LI;
-
- /*
- * Get new line/col info.
- */
- ttsize();
-
- /*
- * LI has changed, and now holds the
- * new value.
- */
- /*
- * Go through the window list, changing each window size in
- * proportion to the resize. If a window becomes too small,
- * delete it. We keep track of all the excess lines (caused by
- * roundoff!), and give them to the current window, as a sop -
- * can't be more than one or two lines anyway. This seems fairer
- * than just resizing the current window.
- */
- wp = fwind;
- total = 0;
- do {
- newsize = LI * wp->w_height / oldLI;
-
- if (newsize < 2) {
- total += wp->w_height;
- wp = wp->w_next;
- del_wind(wp->w_prev);
- } else {
- wp->w_height = newsize;
- total += newsize;
- wp = wp->w_next;
- }
- } while (wp != fwind);
-
- curwind->w_height += LI - total - 1;
-
- /* Make a new screen structure */
- make_scr();
- /* Do a 'hard' update on the screen - clear and redraw */
- cl_scr(YES);
- flusho();
- redisplay();
-
- #ifdef UNIX
- (void) signal(SIGWINCH, win_reshape);
- #endif
- SIGRETURN;
- }
- #endif
-
- void
-
- #ifdef MAC /* will get args from user, if option key held during launch */
- main()
- {
- int argc;
- char **argv;
- #else
- main(argc, argv)
- int argc;
- char *argv[];
- {
- #endif /* MAC */
- char *cp;
- char ttbuf[MAXTTYBUF];
- #ifndef MSDOS
- # ifndef VMUNIX
- char s_iobuff[LBSIZE],
- s_genbuf[LBSIZE],
- s_linebuf[LBSIZE];
- /* The way I look at it, there ain't no way I is gonna run
- out of stack space UNLESS I have some kind of infinite
- recursive bug. So why use up some valuable memory, when
- there is plenty of space on the stack? (This only matters
- on wimpy pdp11's, of course.) */
-
- iobuff = s_iobuff;
- genbuf = s_genbuf;
- linebuf = s_linebuf;
- # endif
-
- #else /* MSDOS */
- char *getenv();
- #endif /* MSDOS */
-
- #ifdef MAC
- MacInit(); /* initializes all */
- if(make_cache() == 0) exit(-1);
- argc = getArgs(&argv);
- #endif /* MAC */
-
- iniargc = argc;
- iniargv = argv;
-
- if (setjmp(mainjmp)) {
- writef("\rAck! I can't deal with error \"%s\" now.\n\r", mesgbuf);
- finish(6);
- }
-
- #ifdef MSDOS
- /* import the temporary file path from the environment and
- fix the string, so that we can append a slash safely */
-
- if (((cp = getenv("TMP")) || (cp = getenv("TMPDIR"))) &&
- (*cp != '\0')) {
- strcpy(TmpFilePath, cp);
- cp = &TmpFilePath[strlen(TmpFilePath)-1];
- if ((*cp == '/') || (*cp == '\\'))
- *cp = 0;
- }
- ShFlags[0] = switchar();
- #endif /* MSDOS */
-
- getTERM(); /* Get terminal. */
- if (getenv("METAKEY"))
- MetaKey = 1;
- ttsize();
- #ifdef MAC
- InitEvents();
- #else
- InitCM();
- #endif
-
- d_cache_init(); /* initialize the disk buffer cache */
- #ifdef MSDOS
- if ((cp = getenv("COMSPEC")) && (*cp != '\0')) {
- strcpy(Shell, cp);
- }
- if ((cp = getenv("DESCRIBE")) && (*cp != '\0'))
- strcpy(CmdDb, cp);
- #else /* !MSDOS */
- #ifndef MAC
- if ((cp = getenv("SHELL"))!=NULL && (*cp != '\0')) {
- strcpy(Shell, cp);
- }
- #endif
- #endif /* !MSDOS */
-
- make_scr();
- mac_init(); /* Initialize Macros */
- winit(); /* Initialize Window */
- #ifdef IPROCS
- pinit(); /* Pipes/process initialization */
- #endif
- buf_init();
-
- {
- char **argp;
-
- if ((argp = scanvec(argv, "-d"))!=NULL
- #ifdef UNIX
- && chkCWD(argp[1])
- #endif
- )
- setCWD(argp[1]);
- else
- getCWD(); /* After we setup curbuf in case we have to getwd() */
- }
-
- HomeDir = getenv("HOME");
- if (HomeDir == NULL)
- HomeDir = "/";
- HomeLen = strlen(HomeDir);
-
- #ifdef UNIX
- # ifdef SYSV
- swritef(Mailbox, "/usr/mail/%s", getenv("LOGNAME"));
- # else
- swritef(Mailbox, "/usr/spool/mail/%s", getenv("USER"));
- # endif
- #endif
-
- InitKeymaps();
-
- ttinit(); /* initialize terminal (before ~/.joverc) */
- settout(ttbuf); /* not until we know baudrate */
- #ifndef MAC
- ResetTerm();
- #endif
-
- (void) joverc(Joverc); /* system wide .joverc */
- cp = 0;
- #if defined(MSDOS) || defined(UNIX)
- /* If a JOVERC environment variable is set, then use that instead */
- if ((cp = getenv("JOVERC")) && (*cp != '\0'))
- (void) joverc(cp);
- #endif /* MSDOS || UNIX */
- if (!scanvec(argv, "-j") && (!cp || *cp == '\0')) {
- char tmpbuf[100];
-
- swritef(tmpbuf, "%s/.joverc", HomeDir);
- (void) joverc(tmpbuf); /* .joverc in home directory */
- }
-
- #ifndef MSDOS
- if (scanvec(argv, "-r"))
- dorecover();
- if (scanvec(argv, "-rc"))
- FullRecover();
- #endif /* MSDOS */
-
- #ifdef MSDOS
- (void) signal(SIGINT, SIG_IGN);
- break_off(); /* disable ctrl-c checking */
- #endif /* MSDOS */
- #ifdef UNIX
- (void) signal(SIGHUP, finish);
- (void) signal(SIGINT, finish);
- (void) signal(SIGBUS, finish);
- (void) signal(SIGSEGV, finish);
- (void) signal(SIGPIPE, finish);
- (void) signal(SIGTERM, SIG_IGN);
- # if defined(TIOCGWINSZ) && defined(SIGWINCH)
- (void) signal(SIGWINCH, win_reshape);
- # endif
- /* set things up to update the modeline every UpdFreq seconds */
- (void) signal(SIGALRM, updmode);
- (void) alarm((unsigned) (UpdFreq - (time((time_t *) 0) % UpdFreq)));
- #endif /* UNIX */
- cl_scr(1);
- flusho();
- RedrawDisplay(); /* start the redisplay process. */
- DoKeys(YES);
- finish(0);
- }
-
- #ifdef MSDOS
-
- #include <dos.h>
-
- static char break_state;
-
- /* set the break state to off */
- private void
- break_off()
- {
- union REGS regs;
-
- regs.h.ah = 0x33; /* break status */
- regs.h.al = 0x00; /* request current state */
- intdos(®s, ®s);
- break_state = regs.h.dl;
- bdos(0x33, 0, 1); /* turn off break */
- }
-
- /* reset the break state */
- private void
- break_rst()
- {
- bdos(0x33, break_state, 1);
- }
- #endif
-