|
|
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: #include "jove.h" ! 9: #include "io.h" ! 10: #include "termcap.h" ! 11: ! 12: #include <signal.h> ! 13: #include <varargs.h> ! 14: ! 15: #ifdef MSDOS ! 16: # include <io.h> ! 17: # include <process.h> ! 18: #endif ! 19: ! 20: ! 21: #ifdef LINT_ARGS ! 22: private void ! 23: DoShell(char *, char *), ! 24: com_finish(int, char *), ! 25: toerror(int, int), ! 26: closepipe(void); ! 27: ! 28: private int ! 29: okay_error(void), ! 30: openforpipe(void), ! 31: reopenforpipe(void); ! 32: ! 33: private struct error ! 34: * AddError(struct error *, Line *, Buffer *, Line *, int); ! 35: #else ! 36: private void ! 37: DoShell(), ! 38: com_finish(), ! 39: toerror(), ! 40: closepipe(); ! 41: ! 42: private int ! 43: openforpipe(), ! 44: okay_error(), ! 45: reopenforpipe(); ! 46: ! 47: private struct error ! 48: * AddError(); ! 49: #endif ! 50: ! 51: ! 52: /* This disgusting RE search string parses output from the GREP ! 53: family, from the pdp11 compiler, pcc, and lint. Jay (HACK) ! 54: Fenlasen changed this to work for the lint errors. */ ! 55: char ErrFmtStr[256] = "^\\{\",\\}\\([^:\"( \t]*\\)\\{\"\\, line ,:,(\\} *\\([0-9][0-9]*\\)[:)]\ ! 56: \\|:: *\\([^(]*\\)(\\([0-9]*\\))$\ ! 57: \\|( \\([^(]*\\)(\\([0-9]*\\)) ),"; ! 58: ! 59: struct error { ! 60: Buffer *er_buf; /* Buffer error is in */ ! 61: Line *er_mess, /* Actual error message */ ! 62: *er_text; /* Actual error */ ! 63: int er_char; /* char pos of error */ ! 64: struct error *er_prev, /* List of errors */ ! 65: *er_next; ! 66: }; ! 67: ! 68: struct error *cur_error = 0, ! 69: *errorlist = 0; ! 70: Buffer *perr_buf = 0; /* Buffer with error messages */ ! 71: ! 72: int WtOnMk = 1; /* Write the modified files when we make */ ! 73: ! 74: /* Add an error to the end of the list of errors. This is used for ! 75: parse-{C,LINT}-errors and for the spell-buffer command */ ! 76: ! 77: private struct error * ! 78: AddError(laste, errline, buf, line, charpos) ! 79: struct error *laste; ! 80: Line *errline, ! 81: *line; ! 82: Buffer *buf; ! 83: { ! 84: struct error *new = (struct error *) emalloc(sizeof *new); ! 85: ! 86: new->er_prev = laste; ! 87: if (laste) ! 88: laste->er_next = new; ! 89: else { ! 90: if (errorlist) /* Free up old errors */ ! 91: ErrFree(); ! 92: cur_error = errorlist = new; ! 93: } ! 94: laste = new; ! 95: new->er_next = 0; ! 96: new->er_buf = buf; ! 97: new->er_text = line; ! 98: new->er_char = charpos; ! 99: new->er_mess = errline; ! 100: ! 101: return new; ! 102: } ! 103: ! 104: /* Parse errors of the form specified in ErrFmtStr in the current ! 105: buffer. Do a show error of the first error. This is neat because this ! 106: will work for any kind of output that prints a file name and a line ! 107: number on the same line. */ ! 108: ! 109: void ! 110: ErrParse() ! 111: { ! 112: Bufpos *bp; ! 113: char fname[FILESIZE], ! 114: lineno[10], ! 115: REbuf[256], ! 116: *REalts[10]; ! 117: int lnum, ! 118: last_lnum = -1; ! 119: struct error *ep = 0; ! 120: Buffer *buf, ! 121: *lastb = 0; ! 122: Line *err_line; ! 123: ! 124: ErrFree(); /* This is important! */ ! 125: ToFirst(); ! 126: perr_buf = curbuf; ! 127: REcompile(ErrFmtStr, 1, REbuf, REalts); ! 128: /* Find a line with a number on it. */ ! 129: while (bp = docompiled(FORWARD, REbuf, REalts)) { ! 130: SetDot(bp); ! 131: putmatch(1, fname, sizeof fname); ! 132: putmatch(2, lineno, sizeof lineno); ! 133: buf = do_find((Window *) 0, fname, 1); ! 134: if (buf != lastb) { ! 135: lastb = buf; ! 136: last_lnum = -1; /* signals new file */ ! 137: err_line = buf->b_first; ! 138: } ! 139: (void) chr_to_int(lineno, 10, NO, &lnum); ! 140: if (lnum == last_lnum) /* one error per line is nicer */ ! 141: continue; ! 142: if (last_lnum == -1) ! 143: last_lnum = 1; /* that's where we really are */ ! 144: err_line = next_line(err_line, lnum - last_lnum); ! 145: ep = AddError(ep, curline, buf, err_line, 0); ! 146: last_lnum = lnum; ! 147: } ! 148: if (cur_error != 0) ! 149: ShowErr(); ! 150: } ! 151: ! 152: /* Free up all the errors */ ! 153: ! 154: void ! 155: ErrFree() ! 156: { ! 157: register struct error *ep; ! 158: ! 159: for (ep = errorlist; ep != 0; ep = ep->er_next) ! 160: free((char *) ep); ! 161: errorlist = cur_error = 0; ! 162: } ! 163: ! 164: /* Internal next error sets cur_error to the next error, taking the ! 165: argument count, supplied by the user, into consideration. */ ! 166: ! 167: private char errbounds[] = "You're at the %s error.", ! 168: noerrs[] = "No errors!"; ! 169: ! 170: private void ! 171: toerror(forward, num) ! 172: { ! 173: register struct error *e = cur_error; ! 174: ! 175: if (e == 0) ! 176: complain(noerrs); ! 177: if ((forward && (e->er_next == 0)) || ! 178: (!forward && (e->er_prev == 0))) ! 179: complain(errbounds, forward ? "last" : "first"); ! 180: ! 181: while (--num >= 0) { ! 182: if ((e = forward ? e->er_next : e->er_prev) == 0) ! 183: break; ! 184: cur_error = e; ! 185: } ! 186: } ! 187: ! 188: void ! 189: NextError() ! 190: { ! 191: ToError(1); ! 192: } ! 193: ! 194: void ! 195: PrevError() ! 196: { ! 197: ToError(0); ! 198: } ! 199: ! 200: private int ! 201: okay_error() ! 202: { ! 203: return ((inlist(perr_buf->b_first, cur_error->er_mess)) && ! 204: (inlist(cur_error->er_buf->b_first, cur_error->er_text))); ! 205: } ! 206: ! 207: /* Go the the next error, if there is one. Put the error buffer in ! 208: one window and the buffer with the error in another window. ! 209: It checks to make sure that the error actually exists. */ ! 210: ! 211: void ! 212: ToError(forward) ! 213: { ! 214: do { ! 215: toerror(forward, arg_value()); ! 216: } while (!okay_error()); ! 217: ShowErr(); ! 218: } ! 219: ! 220: int EWSize = 20; /* percentage of screen the error window ! 221: should be */ ! 222: ! 223: void ! 224: set_wsize(wsize) ! 225: int wsize; ! 226: { ! 227: wsize = (LI * wsize) / 100; ! 228: if (wsize >= 1 && !one_windp()) ! 229: WindSize(curwind, wsize - (curwind->w_height - 1)); ! 230: } ! 231: ! 232: /* Show the current error, i.e. put the line containing the error message ! 233: in one window, and the buffer containing the actual error in another ! 234: window. */ ! 235: ! 236: void ! 237: ShowErr() ! 238: { ! 239: Window *err_wind, ! 240: *buf_wind; ! 241: ! 242: if (cur_error == 0) ! 243: complain(noerrs); ! 244: if (!okay_error()) { ! 245: rbell(); ! 246: return; ! 247: } ! 248: err_wind = windbp(perr_buf); ! 249: buf_wind = windbp(cur_error->er_buf); ! 250: ! 251: if (err_wind && !buf_wind) { ! 252: SetWind(err_wind); ! 253: pop_wind(cur_error->er_buf->b_name, NO, -1); ! 254: buf_wind = curwind; ! 255: } else if (!err_wind && buf_wind) { ! 256: SetWind(buf_wind); ! 257: pop_wind(perr_buf->b_name, NO, -1); ! 258: err_wind = curwind; ! 259: } else if (!err_wind && !buf_wind) { ! 260: pop_wind(perr_buf->b_name, NO, -1); ! 261: err_wind = curwind; ! 262: pop_wind(cur_error->er_buf->b_name, NO, -1); ! 263: buf_wind = curwind; ! 264: } ! 265: ! 266: /* Put the current error message at the top of its Window */ ! 267: SetWind(err_wind); ! 268: SetLine(cur_error->er_mess); ! 269: SetTop(curwind, (curwind->w_line = cur_error->er_mess)); ! 270: set_wsize(EWSize); ! 271: ! 272: /* now go to the the line with the error in the other window */ ! 273: SetWind(buf_wind); ! 274: DotTo(cur_error->er_text, cur_error->er_char); ! 275: } ! 276: ! 277: char ShcomBuf[128] = {0}; ! 278: ! 279: /* Make a buffer name given the command `command', i.e. "fgrep -n foo *.c" ! 280: will return the buffer name "fgrep". */ ! 281: ! 282: char * ! 283: MakeName(command) ! 284: char *command; ! 285: { ! 286: static char bufname[50]; ! 287: register char *cp = bufname, ! 288: c; ! 289: ! 290: while ((c = *command++) && (c == ' ' || c == '\t')) ! 291: ; ! 292: do ! 293: *cp++ = c; ! 294: while ((c = *command++) && (c != ' ' && c != '\t')); ! 295: *cp = 0; ! 296: strcpy(bufname, basename(bufname)); ! 297: ! 298: return bufname; ! 299: } ! 300: ! 301: /* Run make, first writing all the modified buffers (if the WtOnMk flag is ! 302: non-zero), parse the errors, and go the first error. */ ! 303: ! 304: char make_cmd[128] = "make"; ! 305: ! 306: void ! 307: MakeErrors() ! 308: { ! 309: Window *old = curwind; ! 310: int status, ! 311: compilation; ! 312: ! 313: if (WtOnMk) ! 314: put_bufs(0); ! 315: /* When we're not doing make or cc (i.e., the last command ! 316: was probably a grep or something) and the user just types ! 317: C-X C-E, he probably (possibly, hopefully, usually (in my ! 318: case)) doesn't want to do the grep again but rather wants ! 319: to do a make again; so we ring the bell and insert the ! 320: default command and let the person decide. */ ! 321: ! 322: compilation = (sindex("make", make_cmd) || sindex("cc", make_cmd)); ! 323: if (is_an_arg() || !compilation) { ! 324: if (!compilation) { ! 325: rbell(); ! 326: Inputp = make_cmd; /* insert the default for the user */ ! 327: } ! 328: null_ncpy(make_cmd, ask(make_cmd, "Compilation command: "), ! 329: sizeof (make_cmd) - 1); ! 330: } ! 331: status = UnixToBuf(MakeName(make_cmd), YES, EWSize, YES, Shell, ShFlags, make_cmd, (char *) 0); ! 332: com_finish(status, make_cmd); ! 333: ! 334: ErrParse(); ! 335: ! 336: if (!cur_error) ! 337: SetWind(old); ! 338: } ! 339: ! 340: #ifdef SPELL ! 341: ! 342: void ! 343: SpelBuffer() ! 344: { ! 345: char *Spell = "Spell", ! 346: com[100]; ! 347: Window *savewp = curwind; ! 348: ! 349: put_bufs(0); ! 350: sprintf(com, "spell %s", curbuf->b_fname); ! 351: (void) UnixToBuf(Spell, YES, EWSize, YES, Shell, ShFlags, com, (char *) 0); ! 352: message("[Delete the irrelevant words and then type C-X C-C]"); ! 353: ToFirst(); ! 354: Recur(); ! 355: SetWind(savewp); ! 356: SpelParse(Spell); ! 357: } ! 358: ! 359: void ! 360: SpelWords() ! 361: { ! 362: char *buftospel; ! 363: Buffer *wordsb = curbuf; ! 364: ! 365: if ((buftospel = ask_buf((Buffer *) 0)) == 0) ! 366: return; ! 367: SetBuf(do_select(curwind, buftospel)); ! 368: SpelParse(wordsb->b_name); ! 369: } ! 370: ! 371: void ! 372: SpelParse(bname) ! 373: char *bname; ! 374: { ! 375: Buffer *buftospel, ! 376: *wordsb; ! 377: char wordspel[100]; ! 378: Bufpos *bp; ! 379: struct error *ep = 0; ! 380: ! 381: ErrFree(); /* This is important! */ ! 382: ! 383: buftospel = curbuf; ! 384: wordsb = buf_exists(bname); ! 385: perr_buf = wordsb; /* This is important (buffer containing ! 386: error messages) */ ! 387: SetBuf(wordsb); ! 388: ToFirst(); ! 389: f_mess("Finding misspelled words ... "); ! 390: while (!lastp(curline)) { ! 391: sprintf(wordspel, "\\<%s\\>", linebuf); ! 392: SetBuf(buftospel); ! 393: ToFirst(); ! 394: while (bp = dosearch(wordspel, 1, 1)) { ! 395: SetDot(bp); ! 396: ep = AddError(ep, wordsb->b_dot, buftospel, ! 397: curline, curchar); ! 398: } ! 399: SetBuf(wordsb); ! 400: line_move(FORWARD, 1, NO); ! 401: } ! 402: add_mess("Done."); ! 403: SetBuf(buftospel); ! 404: ShowErr(); ! 405: } ! 406: ! 407: #endif /* SPELL */ ! 408: ! 409: void ! 410: ShToBuf() ! 411: { ! 412: char bufname[128], ! 413: cmd[128]; ! 414: ! 415: strcpy(bufname, ask((char *) 0, "Buffer: ")); ! 416: strcpy(cmd, ask(ShcomBuf, "Command: ")); ! 417: DoShell(bufname, cmd); ! 418: } ! 419: ! 420: void ! 421: ShellCom() ! 422: { ! 423: null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1); ! 424: DoShell(MakeName(ShcomBuf), ShcomBuf); ! 425: } ! 426: ! 427: ShNoBuf() ! 428: { ! 429: int status; ! 430: ! 431: null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1); ! 432: status = UnixToBuf((char *) 0, NO, 0, NO, Shell, ShFlags, ShcomBuf, (char *) 0); ! 433: com_finish(status, ShcomBuf); ! 434: } ! 435: ! 436: Shtypeout() ! 437: { ! 438: int status; ! 439: ! 440: null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1); ! 441: status = UnixToBuf((char *) 0, YES, 0, NO, Shell, ShFlags, ShcomBuf, (char *) 0); ! 442: if (status == 0) ! 443: Typeout("[%s: completed successfully]", ShcomBuf); ! 444: else ! 445: Typeout("[%s: exited (%d)]", ShcomBuf, status); ! 446: TOstop(); ! 447: } ! 448: ! 449: /* Run the shell command into `bufname'. Empty the buffer except when we ! 450: give a numeric argument, in which case it inserts the output at the ! 451: current position in the buffer. */ ! 452: ! 453: private void ! 454: DoShell(bufname, command) ! 455: char *bufname, ! 456: *command; ! 457: { ! 458: Window *savewp = curwind; ! 459: int status; ! 460: ! 461: status = UnixToBuf(bufname, YES, 0, !is_an_arg(), Shell, ! 462: ShFlags, command, (char *) 0); ! 463: com_finish(status, command); ! 464: SetWind(savewp); ! 465: } ! 466: ! 467: private void ! 468: com_finish(status, cmd) ! 469: int status; ! 470: char *cmd; ! 471: { ! 472: s_mess("[%s: ", cmd); ! 473: if (status == 0) ! 474: add_mess("completed successfully"); ! 475: else ! 476: add_mess("exited (%d)", status); ! 477: add_mess("]"); ! 478: } ! 479: ! 480: #ifndef MSDOS ! 481: void ! 482: dowait(pid, status) ! 483: int pid, ! 484: *status; ! 485: { ! 486: # ifndef IPROCS ! 487: ! 488: int rpid; ! 489: ! 490: while ((rpid = wait(status)) != pid) ! 491: ; ! 492: # else ! 493: ! 494: # ifdef BSD4_2 ! 495: # include <sys/wait.h> ! 496: # else ! 497: # include <wait.h> ! 498: # endif ! 499: ! 500: union wait w; ! 501: int rpid; ! 502: ! 503: for (;;) { ! 504: # ifndef BSD4_2 ! 505: rpid = wait2(&w.w_status, 0); ! 506: # else ! 507: rpid = wait3(&w, 0, (struct rusage *) 0); ! 508: # endif ! 509: if (rpid == pid) { ! 510: if (status) ! 511: *status = w.w_status; ! 512: break; ! 513: } else ! 514: kill_off(rpid, w); ! 515: } ! 516: # endif /* IPROCS */ ! 517: } ! 518: #endif /* MSDOS */ ! 519: ! 520: /* Run the command to bufname, erase the buffer if clobber is non-zero, ! 521: and redisplay if disp is non-zero. Leaves current buffer in `bufname' ! 522: and leaves any windows it creates lying around. It's up to the caller ! 523: to fix everything up after we're done. (Usually there's nothing to ! 524: fix up.) */ ! 525: ! 526: /* VARARGS5 */ ! 527: ! 528: int ! 529: UnixToBuf(bufname, disp, wsize, clobber, va_alist) ! 530: char *bufname; ! 531: va_dcl ! 532: { ! 533: #ifndef MSDOS ! 534: int p[2], ! 535: pid, ! 536: status, ! 537: #else /* MSDOS */ ! 538: int p0, ! 539: oldo, ! 540: olde, ! 541: retcode, ! 542: #endif /* MSDOS */ ! 543: eof; ! 544: va_list ap; ! 545: char *argv[32], ! 546: *mess; ! 547: File *fp; ! 548: int (*old_int)(); ! 549: ! 550: va_start(ap); ! 551: make_argv(argv, ap); ! 552: va_end(ap); ! 553: if (bufname != 0 && clobber == YES) ! 554: isprocbuf(bufname); ! 555: if (disp) { ! 556: if (bufname != 0) ! 557: message("Starting up..."); ! 558: else { ! 559: TOstart(argv[0], TRUE); ! 560: Typeout("Starting up..."); ! 561: } ! 562: if (bufname != 0) { ! 563: pop_wind(bufname, clobber, clobber ? B_PROCESS : B_FILE); ! 564: set_wsize(wsize); ! 565: redisplay(); ! 566: } ! 567: } ! 568: /* Now I will attempt to describe how I deal with signals during ! 569: the execution of the shell command. My desire was to be able ! 570: to interrupt the shell command AS SOON AS the window pops up. ! 571: So, if we have JOB_CONTROL (i.e., the new signal mechanism) I ! 572: hold SIGINT, meaning if we interrupt now, we will eventually ! 573: see the interrupt, but not before we are ready for it. We ! 574: fork, the child releases the interrupt, it then sees the ! 575: interrupt, and so exits. Meanwhile the parent ignores the ! 576: signal, so if there was a pending one, it's now lost. ! 577: ! 578: With no JOB_CONTROL, the best behavior you can expect is, when ! 579: you type ^] too very quickly after the window pops up, it may ! 580: be ignored. The behavior BEFORE was that it would interrupt ! 581: JOVE and then you would have to continue JOVE and wait a ! 582: little while longer before trying again. Now that is fixed, ! 583: in that you just have to type it twice. */ ! 584: ! 585: #ifndef MSDOS ! 586: # ifdef IPROCS ! 587: sighold(SIGCHLD); ! 588: # endif ! 589: # ifdef JOB_CONTROL ! 590: sighold(SIGINT); ! 591: # else ! 592: old_int = signal(SIGINT, SIG_IGN), ! 593: # endif ! 594: dopipe(p); ! 595: pid = fork(); ! 596: if (pid == -1) { ! 597: pclose(p); ! 598: complain("[Fork failed]"); ! 599: } ! 600: if (pid == 0) { ! 601: # ifdef IPROCS ! 602: sigrelse(SIGCHLD); /* don't know if this matters */ ! 603: # endif /* IPROCS */ ! 604: (void) signal(SIGINT, SIG_DFL); ! 605: # ifdef JOB_CONTROL ! 606: sigrelse(SIGINT); ! 607: # endif ! 608: (void) close(0); ! 609: (void) open("/dev/null", 0); ! 610: (void) close(1); ! 611: (void) close(2); ! 612: (void) dup(p[1]); ! 613: (void) dup(p[1]); ! 614: pclose(p); ! 615: execv(argv[0], &argv[1]); ! 616: (void) write(1, "Execl failed.\n", 14); ! 617: _exit(1); ! 618: } ! 619: # ifdef JOB_CONTROL ! 620: old_int = signal(SIGINT, SIG_IGN); ! 621: # endif ! 622: (void) close(p[1]); ! 623: fp = fd_open(argv[1], F_READ, p[0], iobuff, LBSIZE); ! 624: #else /* MSDOS */ ! 625: if ((p0 = openforpipe()) < 0) ! 626: complain("cannot make pipe for filter"); ! 627: ! 628: oldo = dup(1); ! 629: olde = dup(2); ! 630: close(1); ! 631: close(2); ! 632: dup(p0); ! 633: dup(1); ! 634: close(p0); ! 635: retcode = spawnv(0, argv[0], &argv[1]); ! 636: p0 = reopenforpipe(); ! 637: close(1); ! 638: close(2); ! 639: dup(oldo); ! 640: dup(olde); ! 641: close(oldo); ! 642: close(olde); ! 643: ! 644: if (retcode < 0) ! 645: complain("[Spawn failed]"); ! 646: ! 647: fp = fd_open(argv[1], F_READ, p0, iobuff, LBSIZE); ! 648: #endif /* MSDOS */ ! 649: do { ! 650: #ifndef MSDOS ! 651: inIOread = 1; ! 652: #endif ! 653: eof = f_gets(fp, genbuf, LBSIZE); ! 654: #ifndef MSDOS ! 655: inIOread = 0; ! 656: #endif ! 657: if (bufname != 0) { ! 658: ins_str(genbuf, YES); ! 659: if (!eof) ! 660: LineInsert(1); ! 661: } else if (disp == YES) ! 662: Typeout("%s", genbuf); ! 663: if (bufname != 0 && disp != 0 && fp->f_cnt <= 0) { ! 664: #ifdef LOAD_AV ! 665: { ! 666: double theavg; ! 667: ! 668: get_la(&theavg); ! 669: if (theavg < 2.0) ! 670: mess = "Screaming along..."; ! 671: else if (theavg < 5.0) ! 672: mess = "Chugging along..."; ! 673: else ! 674: mess = "Crawling along..."; ! 675: } ! 676: #else ! 677: mess = "Chugging along..."; ! 678: #endif /* LOAD_AV */ ! 679: if (bufname != 0) { ! 680: message(mess); ! 681: redisplay(); ! 682: } ! 683: } ! 684: } while (!eof); ! 685: if (disp) ! 686: DrawMesg(NO); ! 687: close_file(fp); ! 688: #ifndef MSDOS ! 689: dowait(pid, &status); ! 690: # ifdef JOB_CONTROL ! 691: (void) sigrelse(SIGINT); ! 692: # endif ! 693: #else /* MSDOS */ ! 694: closepipe(); ! 695: #endif /* MSDOS */ ! 696: (void) signal(SIGINT, old_int); ! 697: #ifndef MSDOS ! 698: # ifdef IPROCS ! 699: sigrelse(SIGCHLD); ! 700: # endif ! 701: return status; ! 702: #else /* MSDOS */ ! 703: # ifdef CHDIR ! 704: getCWD(); ! 705: # endif ! 706: return retcode; ! 707: #endif /* MSDOS */ ! 708: } ! 709: ! 710: #ifndef MSDOS ! 711: #ifdef BSD4_2 ! 712: ! 713: private long SigMask = 0; ! 714: ! 715: #ifndef sigmask ! 716: # define sigmask(s) (1L << ((s)-1)) ! 717: #endif ! 718: ! 719: sighold(sig) ! 720: { ! 721: (void) sigblock(SigMask |= sigmask(sig)); ! 722: } ! 723: ! 724: sigrelse(sig) ! 725: { ! 726: (void) sigsetmask(SigMask &= ~sigmask(sig)); ! 727: } ! 728: ! 729: #endif ! 730: ! 731: #endif /* MSDOS */ ! 732: ! 733: void ! 734: FilterRegion() ! 735: { ! 736: char *cmd = ask((char *) 0, ": %f (through command) ", ProcFmt); ! 737: ! 738: RegToUnix(curbuf, cmd); ! 739: } ! 740: ! 741: /* Send the current region to CMD and insert the output from the ! 742: command into OUT_BUF. */ ! 743: ! 744: void ! 745: RegToUnix(outbuf, cmd) ! 746: Buffer *outbuf; ! 747: char *cmd; ! 748: { ! 749: Mark *m = CurMark(); ! 750: #ifndef MSDOS ! 751: char *tname = mktemp("/tmp/jfilterXXXXXX"), ! 752: combuf[128]; ! 753: #endif /* MSDOS */ ! 754: Window *save_wind = curwind; ! 755: int status, ! 756: error = NO; ! 757: #ifdef MSDOS ! 758: int p0, oldi; ! 759: #endif /* MSDOS */ ! 760: File *fp; ! 761: ! 762: #ifndef MSDOS ! 763: fp = open_file(tname, iobuff, F_WRITE, COMPLAIN, QUIET); ! 764: #else /* MSDOS */ ! 765: p0 = openforpipe(); ! 766: #endif /* MSDOS */ ! 767: CATCH ! 768: #ifdef MSDOS ! 769: fp = fd_open(cmd, F_WRITE, p0, iobuff, LBSIZE); ! 770: #endif /* MSDOS */ ! 771: putreg(fp, m->m_line, m->m_char, curline, curchar, YES); ! 772: DelReg(); ! 773: #ifndef MSDOS ! 774: sprintf(combuf, "%s < %s", cmd, tname); ! 775: #else /* MSDOS */ ! 776: f_close(fp); ! 777: p0 = reopenforpipe(); ! 778: oldi = dup(0); ! 779: close(0); ! 780: dup(p0); ! 781: close(p0); ! 782: #endif /* MSDOS */ ! 783: status = UnixToBuf(outbuf->b_name, NO, 0, outbuf->b_type == B_SCRATCH, ! 784: #ifndef MSDOS ! 785: Shell, ShFlags, combuf, (char *) 0); ! 786: #else /* MSDOS */ ! 787: Shell, ShFlags, cmd, (char *) 0); ! 788: #endif /* MSDOS */ ! 789: ONERROR ! 790: error = YES; ! 791: ENDCATCH ! 792: #ifndef MSDOS ! 793: f_close(fp); ! 794: (void) unlink(tname); ! 795: #else /* MSDOS */ ! 796: close(0); ! 797: open("con", 0); /* dup(oldi); */ ! 798: close(oldi); ! 799: closepipe(); ! 800: #endif /* MSDOS */ ! 801: SetWind(save_wind); ! 802: if (error == NO) ! 803: #ifndef MSDOS ! 804: com_finish(status, combuf); ! 805: #else ! 806: com_finish(status, cmd); ! 807: #endif ! 808: } ! 809: ! 810: void ! 811: isprocbuf(bufname) ! 812: char *bufname; ! 813: { ! 814: Buffer *bp; ! 815: ! 816: if ((bp = buf_exists(bufname)) != 0 && bp->b_type != B_PROCESS) ! 817: confirm("Over-write buffer %s?", bufname); ! 818: } ! 819: ! 820: #ifdef MSDOS ! 821: /* msdos specific hacks to allow for pipes */ ! 822: ! 823: #include <dos.h> ! 824: #include <fcntl.h> ! 825: #include <sys/types.h> ! 826: #include <sys/stat.h> ! 827: ! 828: static char pipeiname[64]; ! 829: static char pipeoname[64]; ! 830: static int pipehandle; ! 831: ! 832: extern char TmpFilePath[]; ! 833: ! 834: private int ! 835: openforpipe() ! 836: { ! 837: sprintf(pipeiname, "%s/%s", TmpFilePath, "Jove-I"); ! 838: sprintf(pipeoname, "%s/%s", TmpFilePath, "Jove-O"); ! 839: ! 840: return(pipehandle = creat(pipeoname, S_IWRITE|S_IREAD)); ! 841: } ! 842: ! 843: private int ! 844: reopenforpipe() ! 845: { ! 846: close(pipehandle); ! 847: unlink(pipeiname); ! 848: rename(pipeoname, pipeiname); ! 849: if ((pipehandle = open(pipeiname, 0)) >= 0) ! 850: return(pipehandle); ! 851: closepipe(); ! 852: return(-1); ! 853: } ! 854: ! 855: private void ! 856: closepipe() ! 857: { ! 858: unlink(pipeoname); ! 859: unlink(pipeiname); ! 860: } ! 861: ! 862: char ! 863: switchar() ! 864: { ! 865: union REGS regs; ! 866: ! 867: regs.h.ah = 0x37; ! 868: regs.h.al = 0; ! 869: intdos(®s, ®s); ! 870: return(regs.h.dl); ! 871: } ! 872: #endif /* MSDOS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.