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