This is jove.c in view mode; [Download] [Up]
/*************************************************************************** * 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 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 #else private #endif void UnsetTerm proto((char *)), do_sgtty proto((void)); /* 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, (char *) &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; } #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); /* Place the cursor at the bottom of the screen. If TE then we might have an alternate page, in which case we return to that alternate page and write the message. */ Placur(ILI, 0); putpad(CE, 1); if (TE != 0) 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); # if defined(IPROCS) && defined(PIPEPROCS) int started; # endif #ifndef MSDOS #ifdef IPROCS SigHold(SIGCHLD); #endif #if defined(TIOCGWINSZ) && defined(SIGWINCH) && defined(SigRelse) SigHold(SIGWINCH); #endif alarm(0); # if defined(IPROCS) && defined(PIPEPROCS) started = kbd_stop(); # endif switch (pid = fork()) { case -1: # if defined(IPROCS) && defined(PIPEPROCS) if (started) (void) kbd_strt(); # endif 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); /* note that curbuf->bfname may be NULL */ execl(Shell, basename(Shell), "-is", pr_name(curbuf->b_fname, NO), (char *)NULL); 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); if (UpdFreq != 0) (void) alarm((unsigned) (UpdFreq - (time((time_t *) 0) % UpdFreq))); # if defined(IPROCS) && defined(PIPEPROCS) if (started) (void) kbd_strt(); # 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; #ifndef MSDOS private #endif 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; # ifndef NeXT if (HZ) lmword[ON] &= ~LTILDE; # endif # 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 if (UpdFreq != 0) (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; int oldCO; /* * Save old number of lines and columns. */ oldLI = LI; oldCO = CO; /* * Get new line/col info (in LI/CO). */ ttsize(); if (LI != oldLI || CO != oldCO) { if (LI != oldLI) { /* * 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. */ register int newsize, total; register Window *wp; 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; } /* LI != oldLI */ /* Make a new screen structure */ make_scr(); /* Do a 'hard' update on the screen - clear and redraw */ cl_scr(YES); flusho(); redisplay(); } /* LI != oldLI || CO != oldCO */ 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 */ #ifdef UNIX /* * Get the temporary and library file paths from the environment. */ { register char ***lfp, *dir, *buf; static char **libfiles[] = { &Recover, &CmdDb, &Joverc, 0 }; if ((dir = getenv("JOVETMP")) && strlen(dir) < (sizeof TmpFilePath - sizeof d_tempfile - 1)) strcpy(TmpFilePath, dir); if (dir = getenv("JOVELIB")) for (lfp = libfiles; *lfp; lfp++) { if (!(cp = strrchr(**lfp, '/'))) continue; cp++; buf = emalloc(strlen(cp) + strlen(dir) + 2); sprintf(buf, "%s/%s", dir, cp); **lfp = buf; } } #endif /* UNIX */ getTERM(); /* Get terminal. */ #ifndef METAKEY if (getenv("METAKEY")) #endif /* 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 M_XENIX swritef(Mailbox, "/usr/spool/mail/%s", getenv("USER")); # else # ifdef SYSV swritef(Mailbox, "/usr/mail/%s", getenv("LOGNAME")); # else swritef(Mailbox, "/usr/spool/mail/%s", getenv("USER")); # endif # 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"))!=NULL && (*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); if (UpdFreq != 0) (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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.