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