|
|
1.1 root 1: /***************************************************************************
2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
3: * is provided to you without charge, and with no warranty. You may give *
4: * away copies of JOVE, including sources, provided that this notice is *
5: * included in all the files. *
6: ***************************************************************************/
7:
8: /* Contains the main loop initializations, and some system dependent
9: type things, e.g. putting terminal in CBREAK mode, etc. */
10:
11: #include "jove.h"
12: #include "io.h"
13: #include "termcap.h"
14:
15: #ifdef MAC
16: # include "mac.h"
17: #else
18: # include <varargs.h>
19: # include <sys/stat.h>
20: #endif
21:
22: #include <signal.h>
23: #include <errno.h>
24:
25: #ifdef UNIX
26: # ifndef SYSV
27: # include <sgtty.h>
28: # else
29: # include <termio.h>
30: # endif /* SYSV */
31: #endif /* UNIX */
32:
33: #ifdef MSDOS
34: # include <process.h>
35: #endif /* MSDOS */
36:
37: #ifndef MAC
38: # include <fcntl.h>
39: #endif
40:
41: #ifdef MAC
42: # undef private
43: # define private
44: #endif
45:
46: #ifdef LINT_ARGS
47: extern long time(long *);
48: private void break_off(void);
49: private void break_rst(void);
50: #else
51: extern long time();
52: private void break_off();
53: private void break_rst();
54: #endif
55:
56: #ifdef MAC
57: # undef private
58: # define private static
59: #endif
60:
61: #ifdef UNIX
62: # ifdef TIOCSLTC
63: struct ltchars ls1, ls2;
64: # endif /* TIOCSLTC */
65:
66: # ifdef TIOCGETC
67: struct tchars tc1, tc2;
68: # endif
69:
70: # ifdef PASS8 /* use pass8 instead of raw for meta-key */
71: int lmword1, lmword2; /* local mode word */
72: # endif
73:
74: # ifdef BRLUNIX
75: struct sg_brl sg1, sg2;
76: # else
77: # ifdef SYSV
78: struct termio sg1, sg2;
79: # else /* SYSV */
80: struct sgttyb sg1, sg2;
81: # endif /* SYSV */
82: # endif /* BRLUNIX */
83:
84: # ifdef BIFF
85: private struct stat tt_stat; /* for biff */
86: # ifndef BSD4_2
87: private char *tt_name = 0; /* name of the control tty */
88: extern char *ttyname(); /* for systems w/o fchmod ... */
89: # endif
90: private int dw_biff = NO; /* whether or not to fotz at all */
91: # endif /* BIFF */
92: #endif /* UNIX */
93:
94: int errormsg;
95: extern char *tfname;
96: char NullStr[] = "";
97:
98: #ifdef MSDOS
99: # define SIGHUP 99
100: #endif /* MSDOS */
101:
102: void
103: finish(code)
104: {
105: int CoreDump = (code != 0 && code != SIGHUP),
106: DelTmps = 1; /* Usually we delete them. */
107:
108: if (code == SIGINT) {
109: char c;
110:
111: #ifndef MENLO_JCL
112: (void) signal(code, finish);
113: #endif
114: f_mess("Abort (Type 'n' if you're not sure)? ");
115: #ifndef MSDOS
116: (void) read(0, &c, 1);
117: #else /* MSDOS */
118: c = getrawinchar();
119: #endif /* MSDOS */
120: message(NullStr);
121: if ((c & 0377) != 'y') {
122: redisplay();
123: return;
124: }
125: }
126: ttyset(OFF);
127: UnsetTerm(NullStr);
128: #ifndef MSDOS
129: if (code != 0) {
130: if (!Crashing) {
131: Crashing = YES;
132: lsave();
133: SyncRec();
134: printf("JOVE CRASH!! (code %d)\n", code);
135: if (ModBufs(1)) {
136: printf("Your buffers have been saved.\n");
137: printf("Use \"jove -r\" to have a look at them.\n");
138: DelTmps = 0; /* Don't delete anymore. */
139: } else
140: printf("You didn't lose any work.\n");
141: } else
142: printf("\r\nYou may have lost your work!\n");
143: }
144: #endif /* MSDOS */
145: flusho();
146: if (DelTmps) {
147: tmpclose();
148: #ifndef MSDOS
149: recclose();
150: #endif /* MSDOS */
151: }
152: #ifdef UNIX
153: if (CoreDump)
154: abort();
155: #ifdef PROFILING
156: exit(0);
157: #else
158: _exit(0);
159: #endif
160: #else /* MSDOS or MAC*/
161: #ifdef MSDOS
162: break_rst(); /* restore previous ctrl-c handling */
163: #endif
164: exit(0);
165: #endif /* UNIX */
166: }
167:
168: private char smbuf[20],
169: *bp = smbuf;
170: private int nchars = 0;
171:
172: private char peekbuf[10],
173: *peekp = peekbuf;
174:
175: #if defined(SYSV) || defined(M_XENIX)
176: void
177: setblock(fd, on) /* turn blocking on or off */
178: register int fd, on;
179: {
180: static int blockf, nonblockf;
181: static int first = 1;
182: int flags;
183:
184: if (first) {
185: first = 0;
186: if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
187: finish(SIGHUP);
188: blockf = flags & ~O_NDELAY; /* make sure O_NDELAY is off */
189: nonblockf = flags | O_NDELAY; /* make sure O_NDELAY is on */
190: }
191: if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
192: finish(SIGHUP);
193: }
194: #endif /* SYSV */
195:
196: int
197: Peekc()
198: {
199: int c;
200:
201: if (peekp == peekbuf)
202: c = -1;
203: else
204: c = *--peekp & 0377;
205: return c;
206: }
207:
208: void
209: Ungetc(c)
210: {
211: if (peekp == &peekbuf[(sizeof peekbuf) - 1])
212: return; /* Sorry, can't oblige you ... */
213: *peekp++ = c;
214: }
215:
216: int InputPending = 0;
217:
218: char *Inputp = 0;
219:
220: #if (defined(IPROCS) && !defined(PIPEPROCS)) /* that is, if ptys */
221: getchar()
222: {
223: extern long global_fd;
224: long reads;
225: extern int NumProcs,
226: errno;
227: register int tmp,
228: nfds;
229: int c;
230:
231: if (nchars <= 0) {
232: /* Get a character from the keyboard, first checking for
233: any input from a process. Handle that first, and then
234: deal with the terminal input. */
235: do {
236: do {
237: reads = global_fd;
238: nfds = select(32, &reads, (long *) 0, (long *) 0, (struct timeval *) 0);
239: } while (nfds < 0 && errno == EINTR);
240:
241: if (nfds == -1)
242: complain("\rerror %d in select %ld", errno, global_fd);
243: else {
244: if (reads & 01) {
245: nchars = read(0, smbuf, sizeof(smbuf));
246: reads &= ~01;
247: nfds -= 1;
248: }
249: while (nfds--) {
250: tmp = ffs(reads) - 1;
251: read_proc(tmp);
252: reads &= ~(1L << tmp);
253: }
254: }
255: } while (nchars <= 0);
256:
257: if (nchars <= 0)
258: finish(SIGHUP);
259:
260: bp = smbuf;
261: InputPending = (nchars > 1);
262: }
263:
264: if (((c = *bp) & 0200) && MetaKey != 0) {
265: *bp = (c & CHARMASK);
266: return '\033';
267: }
268: nchars -= 1;
269: return *bp++ & 0377;
270: }
271:
272: #else
273:
274: getchar()
275: {
276: extern int errno;
277: register int c;
278:
279: if (nchars <= 0) {
280: bp = smbuf;
281: #ifdef MSDOS
282: *bp = getrawinchar();
283: nchars = 1;
284: #else
285: do
286: nchars = read(0, smbuf, sizeof smbuf);
287: # ifdef SYSV
288: while (nchars == 0 || (nchars < 0 && errno == EINTR));
289: if (nchars < 0)
290: # else
291: while (nchars < 0 && errno == EINTR);
292: if (nchars <= 0)
293: # endif /* SYSV */
294: finish(SIGHUP);
295: #endif MSDOS
296: InputPending = nchars > 1;
297: }
298: if (((c = *bp) & 0200) && MetaKey != 0) {
299: *bp = (c & CHARMASK);
300: return '\033';
301: }
302: nchars -= 1;
303: return (*bp++ & CHARMASK);
304: }
305:
306: #endif /* IPROCS */
307:
308: /* Returns non-zero if a character waiting */
309:
310: int
311: charp()
312: {
313: #ifndef MSDOS
314: int some = 0;
315: #endif /* MSDOS */
316:
317: if (InJoverc != 0 || nchars > 0 || Inputp != 0)
318: return 1;
319: #ifdef BRLUNIX
320: {
321: static struct sg_brl gttyBuf;
322:
323: gtty(0, (char *) >tyBuf);
324: if (gttyBuf.sg_xflags & INWAIT)
325: some += 1;
326: }
327: #endif
328: #ifdef FIONREAD
329: {
330: long c;
331:
332: if (ioctl(0, FIONREAD, (struct sgttyb *) &c) == -1)
333: c = 0;
334: some = (c > 0);
335: }
336: #endif /* FIONREAD */
337: #if defined(SYSV) || defined(M_XENIX)
338: setblock(0, 0); /* turn blocking off */
339: nchars = read(0, smbuf, sizeof smbuf); /* Is anything there? */
340: setblock(0, 1); /* turn blocking on */
341: if (nchars > 0) /* something was there */
342: bp = smbuf; /* make sure bp points to it */
343: some = (nchars > 0); /* just say we found something */
344: #endif /* SYSV */
345: #ifdef c70
346: some = !empty(0);
347: #endif
348: #ifdef MSDOS
349: return rawkey_ready();
350: #else
351: #ifdef MAC
352: some = rawchkc();
353: #endif
354: return some;
355: #endif /* MSDOS */
356: }
357:
358: #ifdef TERMCAP
359: void
360: ResetTerm()
361: {
362: putpad(TI, 1);
363: putpad(VS, 1);
364: putpad(KS, 1);
365: #ifndef MSDOS
366: (void) chkmail(YES); /* force it to check to we can be accurate */
367: #endif
368: #ifdef BIFF
369: if (BiffChk != dw_biff)
370: biff_init();
371: /* just in case we changed our minds about whether to deal with
372: biff */
373: #endif
374: do_sgtty(); /* this is so if you change baudrate or stuff
375: like that, JOVE will notice. */
376: ttyset(ON);
377: }
378:
379: void
380: UnsetTerm(mesg)
381: char *mesg;
382: {
383: ttyset(OFF);
384: putpad(KE, 1);
385: putpad(VE, 1);
386: putpad(TE, 1);
387: #ifdef ID_CHAR
388: INSmode(0);
389: #endif
390: Placur(ILI, 0);
391: printf("%s", mesg);
392: putpad(CE, 1);
393: flusho();
394: }
395: #endif /* TERMCAP */
396:
397: #ifdef JOB_CONTROL
398: PauseJove()
399: {
400: UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
401: (void) kill(0, SIGTSTP);
402: ResetTerm();
403: ClAndRedraw();
404: }
405: #endif
406:
407:
408: #ifndef MAC
409: void
410: Push()
411: {
412: int
413: #ifndef MSDOS
414: pid,
415: (*old_quit)() = signal(SIGQUIT, SIG_IGN),
416: #endif /* MSDOS */
417: (*old_int)() = signal(SIGINT, SIG_IGN);
418:
419: #ifndef MSDOS
420: #ifdef IPROCS
421: sighold(SIGCHLD);
422: #endif
423: switch (pid = fork()) {
424: case -1:
425: complain("[Fork failed]");
426:
427: case 0:
428: UnsetTerm(NullStr);
429: #ifdef IPROCS
430: sigrelse(SIGCHLD);
431: #endif
432: (void) signal(SIGTERM, SIG_DFL);
433: #else /* MSDOS */
434: UnsetTerm(NullStr);
435: #endif /* MSDOS */
436: (void) signal(SIGINT, SIG_DFL);
437: #ifdef UNIX
438: (void) signal(SIGQUIT, SIG_DFL);
439: execl(Shell, basename(Shell), (char *)0);
440: message("[Execl failed]");
441: _exit(1);
442: }
443: dowait(pid, (int *) 0);
444: #ifdef IPROCS
445: sigrelse(SIGCHLD);
446: #endif
447: #endif /* UNIX */
448: #ifdef MSDOS
449: break_rst();
450: if (spawnl(0, Shell, basename(Shell), (char *)0) == -1)
451: message("[Spawn failed]");
452: #endif /* MSDOS */
453: ResetTerm();
454: ClAndRedraw();
455: #ifndef MSDOS
456: (void) signal(SIGQUIT, old_quit);
457: #else /* MSDOS */
458: break_off();
459: #ifdef CHDIR
460: getCWD();
461: #endif
462: #endif /* MSDOS */
463: (void) signal(SIGINT, old_int);
464: }
465: #endif /* MAC */
466:
467: int OKXonXoff = 0, /* ^S and ^Q initially DON'T work */
468: IntChar = CTL(']');
469:
470: void
471: ttsize()
472: {
473: #ifdef UNIX
474: # ifdef TIOCGWINSZ
475: struct winsize win;
476:
477: if (ioctl (0, TIOCGWINSZ, &win) == 0) {
478: if (win.ws_col)
479: CO = win.ws_col;
480: if (win.ws_row)
481: LI = win.ws_row;
482: }
483: # else /* TIOCGWINSZ */
484: # ifdef BTL_BLIT
485: #include <sys/jioctl.h>
486: struct jwinsize jwin;
487:
488: if (ioctl(0, JWINSIZE, &jwin) == 0) {
489: if (jwin.bytesx)
490: CO = jwin.bytesx;
491: if (jwin.bytesy)
492: LI = jwin.bytesy;
493: }
494: # endif /* BTL_BLIT */
495: # endif /* TIOCGWINSZ */
496: #endif /* UNIX */
497: ILI = LI - 1;
498: }
499:
500: #ifdef BIFF
501: biff_init()
502: {
503: dw_biff = ((BiffChk) &&
504: # ifndef BSD4_2
505: ((tt_name != 0) || (tt_name = ttyname(0))) &&
506: (stat(tt_name, &tt_stat) != -1) &&
507: # else
508: (fstat(0, &tt_stat) != -1) &&
509: # endif
510: (tt_stat.st_mode & S_IEXEC)); /* he's using biff */
511:
512: }
513:
514: biff(on)
515: {
516: if (dw_biff == NO)
517: return;
518: # ifndef BSD4_2
519: (void) chmod(tt_name, on ? tt_stat.st_mode :
520: (tt_stat.st_mode & ~S_IEXEC));
521: # else
522: (void) fchmod(0, on ? tt_stat.st_mode :
523: (tt_stat.st_mode & ~S_IEXEC));
524: # endif
525: }
526:
527: #endif /* BIFF */
528:
529: void
530: ttinit()
531: {
532: #ifdef BIFF
533: biff_init();
534: #endif
535: #ifdef TIOCSLTC
536: (void) ioctl(0, TIOCGLTC, (struct sgttyb *) &ls1);
537: ls2 = ls1;
538: ls2.t_suspc = (char) -1;
539: ls2.t_dsuspc = (char) -1;
540: ls2.t_flushc = (char) -1;
541: ls2.t_lnextc = (char) -1;
542: #endif
543:
544: #ifdef TIOCGETC
545: /* Change interupt and quit. */
546: (void) ioctl(0, TIOCGETC, (struct sgttyb *) &tc1);
547: tc2 = tc1;
548: tc2.t_intrc = IntChar;
549: tc2.t_quitc = (char) -1;
550: if (OKXonXoff) {
551: tc2.t_stopc = (char) -1;
552: tc2.t_startc = (char) -1;
553: }
554: #endif /* TIOCGETC */
555: do_sgtty();
556: }
557:
558: private int done_ttinit = 0;
559:
560: void
561: do_sgtty()
562: {
563: #ifdef UNIX
564: # ifdef SYSV
565: (void) ioctl(0, TCGETA, (char *) &sg1);
566: # else
567: (void) gtty(0, &sg1);
568: # endif /* SYSV */
569: sg2 = sg1;
570:
571: # ifdef LPASS8
572: (void) ioctl(0, TIOCLGET, &lmword1);
573: lmword2 = lmword1;
574: if (MetaKey == YES)
575: lmword2 |= LPASS8;
576: # endif
577:
578: # ifdef SYSV
579: TABS = !((sg1.c_oflag & TAB3) == TAB3);
580: ospeed = sg1.c_cflag & CBAUD;
581:
582: if (OKXonXoff)
583: sg2.c_iflag &= ~(IXON | IXOFF);
584: sg2.c_iflag &= ~(INLCR|ICRNL|IGNCR);
585: sg2.c_lflag &= ~(ISIG|ICANON|ECHO);
586: sg2.c_oflag &= ~(OCRNL|ONLCR);
587: sg2.c_cc[VMIN] = sizeof smbuf;
588: sg2.c_cc[VTIME] = 1;
589: # else
590: TABS = !(sg1.sg_flags & XTABS);
591: ospeed = sg1.sg_ospeed;
592: # ifdef BRLUNIX
593: sg2.sg_flags &= ~(ECHO | CRMOD);
594: sg2.sg_flags |= CBREAK;
595:
596: /* VT100 Kludge: leave STALL on for flow control if DC3DC1 (Yuck.) */
597: sg2.sg_xflags &= ~((sg2.sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
598: # else
599: sg2.sg_flags &= ~(ECHO | CRMOD);
600: # endif /* BRLUNIX */
601:
602: # ifdef PURDUE_EE
603: # ifdef pdp11
604: sg2.sg_flags |= RAW;
605: # else
606: sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
607: # endif
608: # else
609: # ifdef LPASS8
610: sg2.sg_flags |= CBREAK;
611: # else
612: sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
613: # endif
614: # endif /* PURDUE_EE */
615: # endif /* SYSV */
616: #endif /* UNIX */
617:
618: #ifdef MSDOS
619: # ifndef IBMPC
620: setmode(1, 0x8000);
621: # endif /* IBMPC */
622: TABS = 0;
623: #endif /* MSDOS */
624: }
625:
626: void
627: tty_reset()
628: {
629: if (!done_ttinit)
630: return;
631: ttyset(OFF); /* go back to original modes */
632: ttinit();
633: ttyset(ON);
634: }
635:
636: /* If n is OFF reset to original modes */
637:
638: void
639: ttyset(n)
640: {
641: if (!done_ttinit && n == 0) /* Try to reset before we've set! */
642: return;
643: #ifdef UNIX
644: # ifdef SYSV
645: (void) ioctl(0, TCSETAW, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
646: # else
647: # ifdef BRLUNIX
648: (void) stty(0, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
649: # else
650: (void) ioctl(0, TIOCSETN, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
651: # endif /* BRLUNIX */
652: # endif /* SYSV */
653:
654: # ifdef TIOCSETC
655: (void) ioctl(0, TIOCSETC, n == 0 ? (struct sgttyb *) &tc1 : (struct sgttyb *) &tc2);
656: # endif /* TIOCSETC */
657: # ifdef TIOCSLTC
658: (void) ioctl(0, TIOCSLTC, n == 0 ? (struct sgttyb *) &ls1 : (struct sgttyb *) &ls2);
659: # endif /* TIOCSLTC */
660: # ifdef LPASS8
661: (void) ioctl(0, TIOCLSET, n == 0 ? &lmword1 : &lmword2);
662: # endif
663: #endif /* UNIX */
664:
665: #ifdef MSDOS
666: # ifndef IBMPC
667: setmode(1, n == 0 ? 0x4000 : 0x8000);
668: # endif
669: #endif /* MSDOS */
670: done_ttinit = 1;
671: #ifdef BIFF
672: biff(!n);
673: #endif
674: }
675:
676: int this_cmd,
677: last_cmd;
678:
679: void
680: dispatch(c)
681: register int c;
682: {
683: data_obj *cp;
684:
685: this_cmd = 0;
686: cp = mainmap[c & CHARMASK];
687:
688: if (cp == 0) {
689: rbell();
690: clr_arg_value();
691: errormsg = NO;
692: message(NullStr);
693: } else
694: ExecCmd(cp);
695: }
696:
697: int LastKeyStruck,
698: MetaKey = 0;
699:
700: int
701: getch()
702: {
703: register int c,
704: peekc;
705: #ifdef IPROCS
706: extern int NumProcs;
707: #endif
708: extern int ModCount,
709: Interactive;
710:
711: if (Inputp) {
712: if ((c = *Inputp++) != 0)
713: return LastKeyStruck = c;
714: Inputp = 0;
715: }
716:
717: if (InJoverc)
718: return EOF; /* somethings wrong if Inputp runs out while
719: we're reading a .joverc file. */
720:
721: #ifndef MSDOS
722: if (ModCount >= SyncFreq) {
723: ModCount = 0;
724: SyncRec();
725: }
726: #endif /* MSDOS */
727:
728: /* If we're not interactive and we're not executing a macro,
729: AND there are no ungetc'd characters, we read from the
730: terminal (i.e., getch()). And characters only get put
731: in macros from inside this if. */
732: if (((peekc = c = Peekc()) == -1) && (Interactive || ((c = mac_getc()) == -1))) {
733: /* So messages that aren't error messages don't
734: hang around forever. */
735: if (!UpdMesg && !Asking) { /* Don't erase if we are asking */
736: if (mesgbuf[0] && !errormsg)
737: message(NullStr);
738: }
739: redisplay();
740: #if defined(IPROCS) && defined(PIPEPROCS)
741: if (NumProcs > 0) {
742: sigrelse(INPUT_SIG);
743: sigrelse(SIGCHLD);
744: }
745: #endif
746: #ifdef UNIX
747: inIOread = 1;
748: #endif
749: if ((c = getchar()) == EOF)
750: finish(SIGHUP);
751: #ifdef UNIX
752: inIOread = 0;
753: #endif
754:
755: #if defined(IPROCS) && defined(PIPEPROCS)
756: if (NumProcs > 0) {
757: sighold(INPUT_SIG);
758: sighold(SIGCHLD);
759: }
760: #endif
761: if (!Interactive && InMacDefine)
762: mac_putc(c);
763: }
764: if (peekc == -1) /* don't add_stroke peekc's */
765: add_stroke(c);
766: return LastKeyStruck = c;
767: }
768:
769: #ifdef UNIX
770: dorecover()
771: {
772: execl(Recover, "recover", "-d", TmpFilePath, (char *) 0);
773: printf("%s: execl failed!\n", Recover);
774: flusho();
775: _exit(-1);
776: }
777: #endif /* UNIX */
778:
779: void
780: ShowVersion()
781: {
782: extern char *version;
783:
784: s_mess("Jonathan's Own Version of Emacs (%s)", version);
785: }
786:
787: void
788: UNIX_cmdline(argc, argv)
789: char *argv[];
790: {
791: int lineno = 0,
792: nwinds = 1;
793: Buffer *b;
794:
795: ShowVersion();
796: while (argc > 1) {
797: if (argv[1][0] != '-' && argv[1][0] != '+') {
798: int force = (nwinds > 0 || lineno != 0);
799:
800: #ifdef MSDOS
801: strlwr(argv[1]);
802: #endif
803: minib_add(argv[1], force ? YES : NO);
804: b = do_find(nwinds > 0 ? curwind : (Window *) 0,
805: argv[1], force);
806: if (force) {
807: SetABuf(curbuf);
808: SetBuf(b);
809: if (lineno >= 0)
810: SetLine(next_line(curbuf->b_first, lineno));
811: else
812: SetLine(curbuf->b_last);
813: if (nwinds > 1)
814: NextWindow();
815: if (nwinds)
816: nwinds -= 1;
817: }
818: lineno = 0;
819: } else switch (argv[1][1]) {
820: case 'd':
821: argv += 1;
822: argc -= 1;
823: break;
824:
825: case 'j': /* Ignore .joverc in HOME */
826: break;
827: #ifndef MAC
828: case 'p':
829: argv += 1;
830: argc -= 1;
831: if (argv[1] != 0) {
832: SetBuf(do_find(curwind, argv[1], 0));
833: ErrParse();
834: nwinds = 0;
835: }
836: break;
837: #endif
838: case 't':
839: /* check if syntax is -tTag or -t Tag */
840: if (argv[1][2] != 0) {
841: find_tag(&(argv[1][2]), YES);
842: } else {
843: argv += 1;
844: argc -= 1;
845: if (argv[1] != 0)
846: find_tag(argv[1], YES);
847: }
848: break;
849:
850: case 'w':
851: if (argv[1][2] == '\0')
852: nwinds += 1;
853: else {
854: int n;
855:
856: (void) chr_to_int(&argv[1][2], 10, NO, &n);
857: nwinds += -1 + n;
858: }
859: (void) div_wind(curwind, nwinds - 1);
860: break;
861:
862: case '0':
863: case '1':
864: case '2':
865: case '3':
866: case '4':
867: case '5':
868: case '6':
869: case '7':
870: case '8':
871: case '9':
872: (void) chr_to_int(&argv[1][1], 10, NO, &lineno);
873: lineno -= 1;
874: break;
875: case 0:
876: lineno = -1; /* goto end of file ... */
877: break; /* just like some people's */
878: } /* favourite editor */
879: argv += 1;
880: argc -= 1;
881: }
882: }
883:
884: /* VARARGS1 */
885:
886: void
887: error(fmt, va_alist)
888: char *fmt;
889: va_dcl
890: {
891: va_list ap;
892:
893: if (fmt) {
894: va_start(ap);
895: format(mesgbuf, sizeof mesgbuf, fmt, ap);
896: va_end(ap);
897: UpdMesg = YES;
898: }
899: rbell();
900: longjmp(mainjmp, ERROR);
901: }
902:
903: /* VARARGS1 */
904:
905: void
906: complain(fmt, va_alist)
907: char *fmt;
908: va_dcl
909: {
910: va_list ap;
911:
912: if (fmt) {
913: va_start(ap);
914: format(mesgbuf, sizeof mesgbuf, fmt, ap);
915: va_end(ap);
916: UpdMesg = YES;
917: }
918: rbell();
919: longjmp(mainjmp, COMPLAIN);
920: }
921:
922: /* VARARGS1 */
923:
924: void
925: confirm(fmt, va_alist)
926: char *fmt;
927: va_dcl
928: {
929: char *yorn;
930: va_list ap;
931:
932: va_start(ap);
933: format(mesgbuf, sizeof mesgbuf, fmt, ap);
934: va_end(ap);
935: yorn = ask((char *) 0, mesgbuf);
936: if (*yorn != 'Y' && *yorn != 'y')
937: longjmp(mainjmp, COMPLAIN);
938: }
939:
940: int RecDepth = 0;
941:
942: void
943: Recur()
944: {
945: char bname[128];
946: Mark *m;
947:
948: sprintf(bname, "%s", curbuf->b_name);
949: m = MakeMark(curline, curchar, M_FLOATER);
950:
951: RecDepth += 1;
952: UpdModLine = YES;
953: DoKeys(1); /* 1 means not first time */
954: UpdModLine = YES;
955: RecDepth -= 1;
956: SetBuf(do_select(curwind, bname));
957: if (!is_an_arg())
958: ToMark(m);
959: DelMark(m);
960: }
961:
962: jmp_buf mainjmp;
963:
964: #ifdef MAC
965: jmp_buf auxjmp;
966: #endif
967:
968: int iniargc; /* main sets these for DoKeys() */
969: char **iniargv;
970:
971: void
972: DoKeys(nocmdline)
973: {
974: int c;
975: jmp_buf savejmp;
976:
977: push_env(savejmp);
978:
979: switch (setjmp(mainjmp)) {
980: case 0:
981: if (!nocmdline)
982: UNIX_cmdline(iniargc, iniargv);
983: break;
984:
985: case QUIT:
986: if (RecDepth == 0) {
987: if (ModMacs()) {
988: rbell();
989: if (CharUpcase(*ask("No",
990: "Some MACROS haven't been saved; leave anyway? ")) != 'Y')
991: break;
992: }
993: if (ModBufs(0)) {
994: rbell();
995: if (CharUpcase(*ask("No",
996: "Some buffers haven't been saved; leave anyway? ")) != 'Y')
997: break;
998: }
999: #ifdef IPROCS
1000: KillProcs();
1001: #endif
1002: }
1003: pop_env(savejmp);
1004: return;
1005:
1006: case ERROR:
1007: getDOT(); /* God knows what state linebuf was in */
1008:
1009: case COMPLAIN:
1010: {
1011: extern int DisabledRedisplay;
1012:
1013: gc_openfiles(); /* close any files we left open */
1014: errormsg = YES;
1015: unwind_macro_stack();
1016: Asking = 0;
1017: curwind->w_bufp = curbuf;
1018: DisabledRedisplay = NO;
1019: redisplay();
1020: break;
1021: }
1022: }
1023:
1024: this_cmd = last_cmd = 0;
1025:
1026: for (;;) {
1027: #ifdef MAC
1028: setjmp(auxjmp);
1029: #endif
1030: if (this_cmd != ARG_CMD) {
1031: clr_arg_value();
1032: last_cmd = this_cmd;
1033: init_strokes();
1034: }
1035: #ifdef MAC
1036: HiliteMenu(0);
1037: EventCmd = 0;
1038: menus_on();
1039: #endif
1040: c = getch();
1041: if (c == -1)
1042: continue;
1043: dispatch(c);
1044: }
1045: }
1046:
1047: int Crashing = 0;
1048:
1049: char **
1050: scanvec(args, str)
1051: register char **args,
1052: *str;
1053: {
1054: while (*args) {
1055: if (strcmp(*args, str) == 0)
1056: return args;
1057: args += 1;
1058: }
1059: return 0;
1060: }
1061:
1062: #ifdef UNIX
1063: int UpdFreq = 30,
1064: inIOread = 0;
1065:
1066: updmode()
1067: {
1068: UpdModLine = YES;
1069: if (inIOread)
1070: redisplay();
1071: #ifndef JOB_CONTROL
1072: (void) signal(SIGALRM, updmode);
1073: #endif
1074: (void) alarm((unsigned) UpdFreq);
1075: }
1076: #endif /* UNIX */
1077:
1078: #ifndef MSDOS
1079: # if defined(TIOCGWINSZ) && defined(SIGWINCH)
1080: extern win_reshape();
1081: # endif
1082: #else /* MSDOS */
1083: # ifndef IBMPC
1084: char ttbuf[BUFSIZ];
1085: # endif /* IBMPC */
1086: #endif /* MSDOS */
1087:
1088: #if defined(TIOCGWINSZ) && defined(SIGWINCH)
1089: win_reshape()
1090: {
1091: register int oldsize;
1092: register int newsize, total;
1093: register Window *wp;
1094:
1095: (void) signal(SIGWINCH, SIG_IGN);
1096:
1097: /*
1098: * Save old number of lines.
1099: */
1100: oldsize = LI;
1101:
1102: /*
1103: * Get new line/col info.
1104: */
1105: ttsize();
1106:
1107: /*
1108: * LI has changed, and now holds the
1109: * new value.
1110: */
1111: /*
1112: * Go through the window list, changing each window size in
1113: * proportion to the resize. If a window becomes too small,
1114: * delete it. We keep track of all the excess lines (caused by
1115: * roundoff!), and give them to the current window, as a sop -
1116: * can't be more than one or two lines anyway. This seems fairer
1117: * than just resizing the current window.
1118: */
1119: wp = fwind;
1120: total = 0;
1121: do {
1122: newsize = LI * wp->w_height / oldsize;
1123:
1124: if (newsize < 2) {
1125: total += wp->w_height;
1126: wp = wp->w_next;
1127: del_wind(wp->w_prev);
1128: } else {
1129: wp->w_height = newsize;
1130: total += newsize;
1131: wp = wp->w_next;
1132: }
1133: } while (wp != fwind);
1134:
1135: curwind->w_height += LI - total - 1;
1136:
1137: /* Make a new screen structure */
1138: make_scr();
1139: /* Do a 'hard' update on the screen - clear and redraw */
1140: cl_scr(1);
1141: flusho();
1142: redisplay();
1143:
1144: (void) signal(SIGWINCH, win_reshape);
1145: }
1146: #endif
1147:
1148: void
1149:
1150: #ifdef MAC /* will get args from user, if option key held during launch */
1151: main()
1152: {
1153: int argc;
1154: char **argv;
1155: #else
1156: main(argc, argv)
1157: char *argv[];
1158: {
1159: #endif /* MAC */
1160: char *cp;
1161: #ifndef MSDOS
1162: char ttbuf[MAXTTYBUF],
1163: # ifndef VMUNIX
1164: s_iobuff[LBSIZE],
1165: s_genbuf[LBSIZE],
1166: s_linebuf[LBSIZE];
1167: /* The way I look at it, there ain't no way I is gonna run
1168: out of stack space UNLESS I have some kind of infinite
1169: recursive bug. So why use up some valuable memory, when
1170: there is plenty of space on the stack? (This only matters
1171: on wimpy pdp11's, of course.) */
1172:
1173: iobuff = s_iobuff;
1174: genbuf = s_genbuf;
1175: linebuf = s_linebuf;
1176: # endif
1177:
1178: #else /* MSDOS */
1179: char *getenv();
1180: #endif /* MSDOS */
1181:
1182: errormsg = 0;
1183:
1184: #ifdef MAC
1185: MacInit(); /* initializes all */
1186: if(make_cache() == 0) exit(-1);
1187: argc = getArgs(&argv);
1188: #endif /* MAC */
1189:
1190: iniargc = argc;
1191: iniargv = argv;
1192:
1193: if (setjmp(mainjmp)) {
1194: printf("\rAck! I can't deal with error \"%s\" now.\n\r", mesgbuf);
1195: finish(0);
1196: }
1197:
1198: #ifdef MSDOS
1199: /* import the temporary file path from the environment and
1200: fix the string, so that we can append a slash safely */
1201:
1202: if (((cp = getenv("TMP")) || (cp = getenv("TMPDIR"))) &&
1203: (*cp != '\0')) {
1204: strcpy(TmpFilePath, cp);
1205: cp = &TmpFilePath[strlen(TmpFilePath)-1];
1206: if ((*cp == '/') || (*cp == '\\'))
1207: *cp = 0;
1208: }
1209: ShFlags[0] = switchar();
1210: #endif /* MSDOS */
1211:
1212: getTERM(); /* Get terminal. */
1213: if (getenv("METAKEY"))
1214: MetaKey = 1;
1215: ttsize();
1216: InitCM();
1217: #ifdef MAC
1218: InitEvents();
1219: #endif
1220:
1221: d_cache_init(); /* initialize the disk buffer cache */
1222: #ifndef MAC
1223: if ((cp = getenv("COMSPEC")) && (*cp != '\0')) {
1224: strcpy(Shell, cp);
1225: }
1226: #endif
1227: #ifdef MSDOS
1228: if ((cp = getenv("DESCRIBE")) && (*cp != '\0'))
1229: strcpy(CmdDb, cp);
1230: #endif /* MSDOS */
1231:
1232: make_scr();
1233: mac_init(); /* Initialize Macros */
1234: winit(); /* Initialize Window */
1235: #ifdef IPROCS
1236: pinit(); /* Pipes/process initialization */
1237: #endif
1238: SetBuf(do_select(curwind, Mainbuf));
1239:
1240: #ifdef CHDIR
1241: {
1242: char **argp;
1243:
1244: if ((argp = scanvec(argv, "-d")) && (argp[1][0] == '/'))
1245: setCWD(argp[1]);
1246: else
1247: getCWD(); /* After we setup curbuf in case we have to getwd() */
1248: }
1249: #endif
1250: HomeDir = getenv("HOME");
1251: if (HomeDir == 0)
1252: HomeDir = "/";
1253: HomeLen = strlen(HomeDir);
1254:
1255: #ifdef UNIX
1256: # ifdef SYSV
1257: sprintf(Mailbox, "/usr/mail/%s", getenv("LOGNAME"));
1258: # else
1259: sprintf(Mailbox, "/usr/spool/mail/%s", getenv("USER"));
1260: # endif
1261: #endif
1262:
1263: #ifdef MSDOS
1264: if ((cp = getenv("JOVERC")) && (*cp != '\0'))
1265: (void) joverc(cp);
1266: #endif /* MSDOS */
1267: (void) joverc(Joverc);
1268: if (!scanvec(argv, "-j")) {
1269: char tmpbuf[100];
1270: sprintf(tmpbuf, "%s/.joverc", HomeDir);
1271: (void) joverc(tmpbuf);
1272: }
1273: #ifndef MSDOS
1274: if (scanvec(argv, "-r"))
1275: dorecover();
1276: if (scanvec(argv, "-rc"))
1277: FullRecover();
1278: #endif /* MSDOS */
1279: ttinit(); /* initialize terminal (after ~/.joverc) */
1280: #ifndef IBMPC
1281: settout(ttbuf); /* not until we know baudrate */
1282: #endif
1283:
1284: #ifdef MSDOS
1285: (void) signal(SIGINT, SIG_IGN);
1286: break_off(); /* disable ctrl-c checking */
1287: #endif /* MSDOS */
1288: #ifdef UNIX
1289: (void) signal(SIGHUP, finish);
1290: (void) signal(SIGINT, finish);
1291: (void) signal(SIGBUS, finish);
1292: (void) signal(SIGSEGV, finish);
1293: (void) signal(SIGPIPE, finish);
1294: (void) signal(SIGTERM, SIG_IGN);
1295: # if defined(TIOCGWINSZ) && defined(SIGWINCH)
1296: (void) signal(SIGWINCH, win_reshape);
1297: # endif
1298: /* set things up to update the modeline every UpdFreq seconds */
1299: (void) signal(SIGALRM, updmode);
1300: (void) alarm((unsigned) (60 - (time((time_t *) 0) % 60)));
1301: #endif /* UNIX */
1302:
1303: ResetTerm();
1304: cl_scr(1);
1305: flusho();
1306: RedrawDisplay(); /* start the redisplay process. */
1307: DoKeys(0);
1308: finish(0);
1309: }
1310:
1311: #ifdef MSDOS
1312:
1313: #include <dos.h>
1314:
1315: static char break_state;
1316:
1317: /* set the break state to off */
1318: private void
1319: break_off()
1320: {
1321: union REGS regs;
1322:
1323: regs.h.ah = 0x33; /* break status */
1324: regs.h.al = 0x00; /* request current state */
1325: intdos(®s, ®s);
1326: break_state = regs.h.dl;
1327: bdos(0x33, 0, 1); /* turn off break */
1328: }
1329:
1330: /* reset the break state */
1331: private void
1332: break_rst()
1333: {
1334: bdos(0x33, break_state, 1);
1335: }
1336: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.