home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume11 / jove.pch / part02 / jove.pch.2
Encoding:
Text File  |  1987-09-15  |  42.7 KB  |  1,999 lines

  1. diff -c ojove/fp.c jove/fp.c
  2. *** ojove/fp.c    Thu Jul 16 09:14:23 1987
  3. --- jove/fp.c    Fri Jun 12 10:30:44 1987
  4. ***************
  5. *** 7,12 ****
  6. --- 7,13 ----
  7.   
  8.   #include "jove.h"
  9.   #include "io.h"
  10. + #include "ctype.h"
  11.   #include "termcap.h"
  12.   #include <sys/stat.h>
  13.   #include <sys/file.h>
  14. ***************
  15. *** 14,22 ****
  16.   
  17.   #define MAXFILES    20    /* good enough for my purposes */
  18.   
  19. ! static File    _openfiles[MAXFILES] = {0};
  20.   
  21. ! static File *
  22.   f_alloc(name, flags, fd, buffer, buf_size)
  23.   char    *name,
  24.       *buffer;
  25. --- 15,23 ----
  26.   
  27.   #define MAXFILES    20    /* good enough for my purposes */
  28.   
  29. ! private File    _openfiles[MAXFILES] = {0};
  30.   
  31. ! private File *
  32.   f_alloc(name, flags, fd, buffer, buf_size)
  33.   char    *name,
  34.       *buffer;
  35. ***************
  36. *** 106,111 ****
  37. --- 107,114 ----
  38.           return EOF;
  39.       fp->f_ptr = fp->f_base;
  40.       fp->f_cnt = read(fp->f_fd, fp->f_base, fp->f_bufsize);
  41. +     while (fp->f_cnt == -1 && errno == EINTR)
  42. +         fp->f_cnt = read(fp->f_fd, fp->f_base, fp->f_bufsize);
  43.       if (fp->f_cnt == -1) {
  44.           printf("[Read error %d]", errno);
  45.           fp->f_flags |= F_ERR;
  46. ***************
  47. *** 147,152 ****
  48. --- 150,166 ----
  49.       _flush(EOF, fp);
  50.   }
  51.   
  52. + f_seek(fp, offset)
  53. + register File    *fp;
  54. + off_t    offset;
  55. + {
  56. +     if (fp->f_flags & F_WRITE)
  57. +         flush(fp);
  58. +     fp->f_cnt = 0;        /* next read will filbuf(), next write
  59. +                    will flush() with no bad effects */
  60. +     lseek(fp->f_fd, (long) offset, L_SET);
  61. + }
  62.   _flush(c, fp)
  63.   register File    *fp;
  64.   {
  65. ***************
  66. *** 182,188 ****
  67.           return EOF;
  68.       while (((c = getc(fp)) != EOF) && (c != '\n')) {
  69.           if (c == NULL)
  70. !             continue;    /* sorry we don't read nulls */
  71.           if (cp >= endp) {
  72.               add_mess(" [Line too long]");
  73.               rbell();
  74. --- 196,202 ----
  75.           return EOF;
  76.       while (((c = getc(fp)) != EOF) && (c != '\n')) {
  77.           if (c == NULL)
  78. !             break;        /* sorry we don't read nulls */
  79.           if (cp >= endp) {
  80.               add_mess(" [Line too long]");
  81.               rbell();
  82. ***************
  83. *** 201,215 ****
  84.       return NIL;    /* this means okay */
  85.   }
  86.   
  87.   /* Deals with output to the terminal, setting up the amount of characters
  88.      to be buffered depending on the output baud rate.  Why it's in a 
  89.      separate file I don't know ... */
  90.   
  91. ! static char    one_buf;
  92.   
  93.   int    BufSize = 1;
  94.   
  95. ! static File    _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf};
  96.   File    *stdout = &_stdout;
  97.   
  98.   /* put a string with padding */
  99. --- 215,264 ----
  100.       return NIL;    /* this means okay */
  101.   }
  102.   
  103. + /* skip to beginning of next line, i.e., next read returns first
  104. +    character of new line */
  105. + f_toNL(fp)
  106. + register File    *fp;
  107. + {
  108. +     register int    c;
  109. +     if (fp->f_flags & F_EOF)
  110. +         return;
  111. +     while (((c = getc(fp)) != EOF) && (c != '\n'))
  112. +         ;
  113. +     if (c == EOF)
  114. +         fp->f_flags |= F_EOF;
  115. + }
  116. + f_readn(fp, addr, n)
  117. + register File    *fp;
  118. + register char    *addr;
  119. + register int    n;
  120. + {
  121. +     while (--n >= 0)
  122. +         *addr++ = getc(fp);
  123. + }
  124. + f_getint(fp)
  125. + File    *fp;
  126. + {
  127. +     int    n = 0,
  128. +         c;
  129. +     while (isdigit(c = getc(fp)))
  130. +         n = (n * 10) + c;
  131. +     return n;
  132. + }
  133.   /* Deals with output to the terminal, setting up the amount of characters
  134.      to be buffered depending on the output baud rate.  Why it's in a 
  135.      separate file I don't know ... */
  136.   
  137. ! private char    one_buf;
  138.   
  139.   int    BufSize = 1;
  140.   
  141. ! private File    _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf};
  142.   File    *stdout = &_stdout;
  143.   
  144.   /* put a string with padding */
  145. diff -c ojove/funcdefs.c jove/funcdefs.c
  146. *** ojove/funcdefs.c    Thu Jul 16 09:14:24 1987
  147. --- jove/funcdefs.c    Fri Jun 12 12:25:57 1987
  148. ***************
  149. *** 6,11 ****
  150. --- 6,12 ----
  151.    ************************************************************************/
  152.   
  153.   #include "jove.h"
  154. + #include "ctype.h"
  155.   
  156.   #ifndef TXT_TO_C
  157.   extern int
  158. ***************
  159. *** 97,103 ****
  160.       ForChar(),
  161.       FSexpr(),
  162.       ForWord(),
  163. !     FourTime(),
  164.       GoLine(),
  165.       GrowWindow(),
  166.       IncFSearch(),
  167. --- 98,104 ----
  168.       ForChar(),
  169.       FSexpr(),
  170.       ForWord(),
  171. !     TimesFour(),
  172.       GoLine(),
  173.       GrowWindow(),
  174.       IncFSearch(),
  175. ***************
  176. *** 167,172 ****
  177. --- 168,174 ----
  178.       SpelBuffer(),
  179.   #endif
  180.       SplitWind(),
  181. +     GotoWind(),
  182.       Remember(),
  183.       Forget(),
  184.       StrLength(),
  185. ***************
  186. *** 354,363 ****
  187. --- 356,367 ----
  188.       FUNCTION, "forward-sentence", WIRED_CMD(Eos),
  189.       FUNCTION, "forward-word", WIRED_CMD(ForWord),
  190.       DefMajor(FUNDAMENTAL), "fundamental-mode", 0,
  191. +     FUNCTION, "gather-numeric-argument", WIRED_CMD(TimesFour),
  192.   #ifdef LISP
  193.       FUNCTION, "grind-s-expr", WIRED_CMD(GSexpr),
  194.   #endif
  195.       FUNCTION, "goto-line", WIRED_CMD(GoLine),
  196. +     FUNCTION, "goto-window-with-buffer", WIRED_CMD(GotoWind),
  197.       FUNCTION, "grow-window", WIRED_CMD(GrowWindow),
  198.       FUNCTION, "handle-tab", WIRED_CMD(Tab),
  199.       FUNCTION, "i-search-forward", WIRED_CMD(IncFSearch),
  200. ***************
  201. *** 432,438 ****
  202.       FUNCTION, "pushd", WIRED_CMD(Pushd),
  203.       FUNCTION, "pwd", WIRED_CMD(prCWD),
  204.   #endif
  205. -     FUNCTION, "quadruple-numeric-argument", WIRED_CMD(FourTime),
  206.       FUNCTION, "query-replace-string", WIRED_CMD(QRepSearch),
  207.   #ifdef IPROCS
  208.       FUNCTION, "quit-process", WIRED_CMD(ProcQuit),
  209. --- 436,441 ----
  210. ***************
  211. *** 520,530 ****
  212.           struct cmd    *which;
  213.           int    cmdlen,
  214.               found = 0;
  215. !         static struct cmd    *cmdhash[1 + 26];
  216.           static int    beenhere = NO;
  217.   
  218.   /* special case for prefix commands--only upper case ones */
  219. ! #define hash(c)    ((c == 'P') ? 0 : 1 + (c - 'a'))
  220.   
  221.           /* initialize the hash table */
  222.           if (beenhere == NO) {
  223. --- 523,533 ----
  224.           struct cmd    *which;
  225.           int    cmdlen,
  226.               found = 0;
  227. !         static struct cmd    *cmdhash[26];
  228.           static int    beenhere = NO;
  229.   
  230.   /* special case for prefix commands--only upper case ones */
  231. ! #define hash(c)    (c - 'a')
  232.   
  233.           /* initialize the hash table */
  234.           if (beenhere == NO) {
  235. ***************
  236. *** 539,546 ****
  237.           }
  238.   
  239.           /* gather the cmd name */
  240. !         while (((c = getch()) != EOF) && !index(" \t\r\n", c))
  241.               *cp++ = c;
  242.           if (c == EOF)
  243.               return 0;
  244.           *cp = '\0';
  245. --- 542,552 ----
  246.           }
  247.   
  248.           /* gather the cmd name */
  249. !         while (((c = getch()) != EOF) && !index(" \t\r\n", c)) {
  250. !             if (isupper(c))
  251. !                 c = tolower(c);
  252.               *cp++ = c;
  253. +         }
  254.           if (c == EOF)
  255.               return 0;
  256.           *cp = '\0';
  257. ***************
  258. *** 549,555 ****
  259.               return 0;
  260.   
  261.           /* look it up (in the reduced search space) */
  262. !         for (cmd = cmdhash[hash(cmdbuf[0])]; cmd->Name[0] == cmdbuf[0]; cmd++) {
  263.               if (strncmp(cmd->Name, cmdbuf, cmdlen) == 0) {
  264.                   if (strcmp(cmd->Name, cmdbuf) == 0)
  265.                       return (data_obj *) cmd;
  266. --- 555,562 ----
  267.               return 0;
  268.   
  269.           /* look it up (in the reduced search space) */
  270. !         if (islower(cmdbuf[0]))
  271. !             for (cmd = cmdhash[hash(cmdbuf[0])]; cmd != 0 && cmd->Name[0] == cmdbuf[0]; cmd++) {
  272.               if (strncmp(cmd->Name, cmdbuf, cmdlen) == 0) {
  273.                   if (strcmp(cmd->Name, cmdbuf) == 0)
  274.                       return (data_obj *) cmd;
  275. ***************
  276. *** 556,562 ****
  277.                   found++;
  278.                   which = cmd;
  279.               }
  280. !         }
  281.           if (found > 1)
  282.               complain("[\"%s\" ambiguous]", cmdbuf);
  283.           else if (found == 0)
  284. --- 563,569 ----
  285.                   found++;
  286.                   which = cmd;
  287.               }
  288. !             }
  289.           if (found > 1)
  290.               complain("[\"%s\" ambiguous]", cmdbuf);
  291.           else if (found == 0)
  292. ***************
  293. *** 565,581 ****
  294.               return (data_obj *) which;
  295.       } else {
  296.           static char    *strings[(sizeof commands) / sizeof (commands[0])];
  297. !         static int    beenhere = 0;
  298.           register int    com;
  299.   
  300. !         if (beenhere == 0) {
  301.               register char    **strs = strings;
  302. !             register struct cmd    *c = commands;
  303.   
  304. !             beenhere = 1;
  305. !             for (; c->Name; c++)
  306.                   *strs++ = c->Name;
  307.               *strs = 0;
  308.           }
  309.   
  310.           if ((com = complete(strings, prompt, CASEIND)) < 0)
  311. --- 572,588 ----
  312.               return (data_obj *) which;
  313.       } else {
  314.           static char    *strings[(sizeof commands) / sizeof (commands[0])];
  315. !         static int    beenhere = NO;
  316.           register int    com;
  317.   
  318. !         if (beenhere == NO) {
  319.               register char    **strs = strings;
  320. !             register struct cmd    *c;
  321.   
  322. !             for (c = commands; c->Name != 0; c++)
  323.                   *strs++ = c->Name;
  324.               *strs = 0;
  325. +             beenhere = YES;
  326.           }
  327.   
  328.           if ((com = complete(strings, prompt, CASEIND)) < 0)
  329. diff -c ojove/insert.c jove/insert.c
  330. *** ojove/insert.c    Thu Jul 16 09:14:25 1987
  331. --- jove/insert.c    Fri Jul 10 09:25:50 1987
  332. ***************
  333. *** 96,108 ****
  334.           incrmt = (tabstop - (dotcol % tabstop));
  335.           if (dotcol + incrmt > goal)
  336.               break;
  337. !         Insert('\t');
  338.           dotcol += incrmt;
  339.       }
  340.       if (dotcol != goal)
  341. !         DoTimes(Insert(' '), (goal - dotcol));
  342. !     exp_p = NO;
  343. !     exp = 1;
  344.   }
  345.   
  346.   SelfInsert()
  347. --- 96,106 ----
  348.           incrmt = (tabstop - (dotcol % tabstop));
  349.           if (dotcol + incrmt > goal)
  350.               break;
  351. !         insert_c('\t', 1);
  352.           dotcol += incrmt;
  353.       }
  354.       if (dotcol != goal)
  355. !         insert_c(' ', (goal - dotcol));
  356.   }
  357.   
  358.   SelfInsert()
  359. ***************
  360. *** 116,132 ****
  361.           register int    num,
  362.                   i;
  363.   
  364. !         for (i = 0, num = exp, exp = 1; i < num; i++) {
  365.               int    pos = calc_pos(linebuf, curchar);
  366.   
  367.               if (!eolp()) {
  368.                   if (linebuf[curchar] == '\t') {
  369.                       if ((pos + 1) == ((pos + tabstop) - (pos % tabstop)))
  370. !                         DelNChar();
  371.                   } else
  372. !                     DelNChar();
  373.               }
  374. !             Insert(LastKeyStruck);
  375.           }
  376.       } else
  377.           Insert(LastKeyStruck);
  378. --- 114,130 ----
  379.           register int    num,
  380.                   i;
  381.   
  382. !         for (i = 0, num = arg_value(); i < num; i++) {
  383.               int    pos = calc_pos(linebuf, curchar);
  384.   
  385.               if (!eolp()) {
  386.                   if (linebuf[curchar] == '\t') {
  387.                       if ((pos + 1) == ((pos + tabstop) - (pos % tabstop)))
  388. !                         del_char(FORWARD, 1);
  389.                   } else
  390. !                     del_char(FORWARD, 1);
  391.               }
  392. !             insert_c(LastKeyStruck, 1);
  393.           }
  394.       } else
  395.           Insert(LastKeyStruck);
  396. ***************
  397. *** 139,151 ****
  398.   
  399.   Insert(c)
  400.   {
  401. !     if (exp <= 0)
  402.           return;
  403.       modify();
  404.       makedirty(curline);
  405. !     ins_c(c, linebuf, curchar, exp, LBSIZE);
  406. !     IFixMarks(curline, curchar, curline, curchar + exp);
  407. !     curchar += exp;
  408.   }    
  409.   
  410.   /* Tab in to the right place for C mode */
  411. --- 137,155 ----
  412.   
  413.   Insert(c)
  414.   {
  415. !     insert_c(c, arg_value());
  416. ! }
  417. ! /* insert character C N times at point */
  418. ! insert_c(c, n)
  419. ! {
  420. !     if (n <= 0)
  421.           return;
  422.       modify();
  423.       makedirty(curline);
  424. !     ins_c(c, linebuf, curchar, n, LBSIZE);
  425. !     IFixMarks(curline, curchar, curline, curchar + n);
  426. !     curchar += n;
  427.   }    
  428.   
  429.   /* Tab in to the right place for C mode */
  430. ***************
  431. *** 159,165 ****
  432.   
  433.           ToIndent();
  434.           if (dotchar > curchar)
  435. !             m = MakeMark(curline, dotchar, FLOATER);
  436.           (void) lisp_indent();
  437.           if (m) {
  438.               ToMark(m);
  439. --- 163,169 ----
  440.   
  441.           ToIndent();
  442.           if (dotchar > curchar)
  443. !             m = MakeMark(curline, dotchar, M_FLOATER);
  444.           (void) lisp_indent();
  445.           if (m) {
  446.               ToMark(m);
  447. ***************
  448. *** 177,191 ****
  449.   
  450.   QuotChar()
  451.   {
  452. !     int    c;
  453. !     extern int    alarmed;    /* If waitfor had to wait. */
  454.   
  455. !     c = waitchar();
  456. !     if (alarmed)
  457.           message(key_strokes);
  458. !     if (c == CTL(J))
  459. !         LineInsert(exp);
  460. !     else if (c != CTL(@))
  461.           Insert(c);
  462.   }
  463.   
  464. --- 181,195 ----
  465.   
  466.   QuotChar()
  467.   {
  468. !     int    c,
  469. !         slow;
  470.   
  471. !     c = waitchar(&slow);
  472. !     if (slow)
  473.           message(key_strokes);
  474. !     if (c == CTL('J'))
  475. !         LineInsert(arg_value());
  476. !     else if (c != CTL('@'))
  477.           Insert(c);
  478.   }
  479.   
  480. ***************
  481. *** 215,224 ****
  482.   #endif
  483.       SelfInsert();
  484.       if (MinorMode(ShowMatch) && !charp() && !in_macro()) {
  485. !         BackChar();    /* Back onto the ')' */
  486.           if ((int) bp == -1)
  487.               bp = m_paren(c, BACKWARD, NO, YES);
  488. !         ForChar();
  489.           if (bp != 0) {
  490.               nx = in_window(curwind, bp->p_line);
  491.               if (nx != -1) {        /* is visible */
  492. --- 219,228 ----
  493.   #endif
  494.       SelfInsert();
  495.       if (MinorMode(ShowMatch) && !charp() && !in_macro()) {
  496. !         b_char(1);    /* Back onto the ')' */
  497.           if ((int) bp == -1)
  498.               bp = m_paren(c, BACKWARD, NO, YES);
  499. !         f_char(1);
  500.           if (bp != 0) {
  501.               nx = in_window(curwind, bp->p_line);
  502.               if (nx != -1) {        /* is visible */
  503. ***************
  504. *** 264,279 ****
  505.   #ifdef LISP
  506.       if (MajorMode(LISPMODE))
  507.           DelWtSpace();
  508.   #endif
  509. !     else if (blnkp(linebuf))
  510.           DelWtSpace();
  511.           
  512.       /* If there is more than 2 blank lines in a row then don't make
  513.          a newline, just move down one. */
  514. !     if (exp == 1 && eolp() && TwoBlank())
  515.           SetLine(curline->l_next);
  516.       else
  517. !         LineInsert(exp);
  518.   
  519.       if (indentp)
  520.   #ifdef LISP
  521. --- 268,284 ----
  522.   #ifdef LISP
  523.       if (MajorMode(LISPMODE))
  524.           DelWtSpace();
  525. +     else
  526.   #endif
  527. !         if (blnkp(linebuf))
  528.           DelWtSpace();
  529.           
  530.       /* If there is more than 2 blank lines in a row then don't make
  531.          a newline, just move down one. */
  532. !     if (arg_value() == 1 && eolp() && TwoBlank())
  533.           SetLine(curline->l_next);
  534.       else
  535. !         LineInsert(arg_value());
  536.   
  537.       if (indentp)
  538.   #ifdef LISP
  539. ***************
  540. *** 292,298 ****
  541.       int    llen;
  542.   
  543.       if (*str == 0)
  544. !         return;    /* ain't nothing to insert! */
  545.       DOTsave(&save);
  546.       llen = strlen(linebuf);
  547.       while (c = *str++) {
  548. --- 297,303 ----
  549.       int    llen;
  550.   
  551.       if (*str == 0)
  552. !         return;        /* ain't nothing to insert! */
  553.       DOTsave(&save);
  554.       llen = strlen(linebuf);
  555.       while (c = *str++) {
  556. ***************
  557. *** 314,328 ****
  558.       makedirty(curline);
  559.   }
  560.   
  561. ! OpenLine()
  562.   {
  563.       Bufpos    dot;
  564.   
  565.       DOTsave(&dot);
  566. !     LineInsert(exp);    /* Open the lines... */
  567.       SetDot(&dot);
  568.   }
  569.   
  570.   /* Take the region FLINE/FCHAR to TLINE/TCHAR and insert it at
  571.      ATLINE/ATCHAR in WHATBUF. */
  572.   
  573. --- 319,338 ----
  574.       makedirty(curline);
  575.   }
  576.   
  577. ! open_lines(n)
  578.   {
  579.       Bufpos    dot;
  580.   
  581.       DOTsave(&dot);
  582. !     LineInsert(n);    /* Open the lines... */
  583.       SetDot(&dot);
  584.   }
  585.   
  586. + OpenLine()
  587. + {
  588. +     open_lines(arg_value());
  589. + }
  590.   /* Take the region FLINE/FCHAR to TLINE/TCHAR and insert it at
  591.      ATLINE/ATCHAR in WHATBUF. */
  592.   
  593. ***************
  594. *** 392,398 ****
  595.   
  596.       /* Now must find a recently killed region. */
  597.   
  598. !     if (exp < 0)
  599.           dir = 1;
  600.   
  601.       killptr += dir;
  602. --- 402,408 ----
  603.   
  604.       /* Now must find a recently killed region. */
  605.   
  606. !     if (arg_value() < 0)
  607.           dir = 1;
  608.   
  609.       killptr += dir;
  610. ***************
  611. *** 468,474 ****
  612.       }
  613.   }
  614.   
  615. ! static
  616.   newchunk()
  617.   {
  618.       register Line    *newline;
  619. --- 478,484 ----
  620.       }
  621.   }
  622.   
  623. ! private
  624.   newchunk()
  625.   {
  626.       register Line    *newline;
  627. ***************
  628. *** 520,526 ****
  629.   /* Remove the free lines, in chunk c, from the free list because they are
  630.      no longer free. */
  631.   
  632. ! static
  633.   remfreelines(c)
  634.   register struct chunk    *c;
  635.   {
  636. --- 530,536 ----
  637.   /* Remove the free lines, in chunk c, from the free list because they are
  638.      no longer free. */
  639.   
  640. ! private
  641.   remfreelines(c)
  642.   register struct chunk    *c;
  643.   {
  644. ***************
  645. *** 584,595 ****
  646.       DOTsave(&dot);
  647.       FSexpr();
  648.       DOTsave(&end);
  649. -     exp = 1;
  650.       SetDot(&dot);
  651.       for (;;) {
  652.           if (curline == end.p_line)
  653.               break;
  654. !         line_move(FORWARD, NO);
  655.           if (!blnkp(linebuf))
  656.               (void) lisp_indent();
  657.       }
  658. --- 594,604 ----
  659.       DOTsave(&dot);
  660.       FSexpr();
  661.       DOTsave(&end);
  662.       SetDot(&dot);
  663.       for (;;) {
  664.           if (curline == end.p_line)
  665.               break;
  666. !         line_move(FORWARD, 1, NO);
  667.           if (!blnkp(linebuf))
  668.               (void) lisp_indent();
  669.       }
  670. ***************
  671. *** 656,662 ****
  672.   
  673.       DOTsave(&savedot);
  674.       SetDot(bp);
  675. !     DoTimes(ForChar(), 1);
  676.       if (linebuf[curchar] != '(') {
  677.           register Word    *wp;
  678.   
  679. --- 665,671 ----
  680.   
  681.       DOTsave(&savedot);
  682.       SetDot(bp);
  683. !     f_char(1);
  684.       if (linebuf[curchar] != '(') {
  685.           register Word    *wp;
  686.   
  687. ***************
  688. *** 669,675 ****
  689.               int    c_char = curchar;
  690.   
  691.               WITH_TABLE(curbuf->b_major)
  692. !                 ForWord();
  693.               END_TABLE();
  694.               if (LookingAt("[ \t]*;\\|[ \t]*$", linebuf, curchar))
  695.                   curchar = c_char;
  696. --- 678,684 ----
  697.               int    c_char = curchar;
  698.   
  699.               WITH_TABLE(curbuf->b_major)
  700. !                 f_word(1);
  701.               END_TABLE();
  702.               if (LookingAt("[ \t]*;\\|[ \t]*$", linebuf, curchar))
  703.                   curchar = c_char;
  704. diff -c ojove/io.c jove/io.c
  705. *** ojove/io.c    Thu Jul 16 09:14:28 1987
  706. --- jove/io.c    Fri Jun 19 16:00:59 1987
  707. ***************
  708. *** 107,115 ****
  709.       }
  710.       DOTsave(&save);
  711.       dofread(fp);
  712. !     SetDot(&save);
  713. !     if (is_insert && io_chars > 0)
  714.           modify();
  715.       getDOT();
  716.       close_file(fp);
  717.   }
  718. --- 107,117 ----
  719.       }
  720.       DOTsave(&save);
  721.       dofread(fp);
  722. !     if (is_insert && io_chars > 0) {
  723.           modify();
  724. +         set_mark();
  725. +     }
  726. +     SetDot(&save);
  727.       getDOT();
  728.       close_file(fp);
  729.   }
  730. ***************
  731. *** 121,127 ****
  732.       int    xeof = 0;
  733.       Line    *savel = curline;
  734.       int    savec = curchar;
  735. !     disk_line    f_getputl() ;
  736.   
  737.       strcpy(end, linebuf + curchar);
  738.       xeof = f_gets(fp, linebuf + curchar, LBSIZE - curchar);
  739. --- 123,129 ----
  740.       int    xeof = 0;
  741.       Line    *savel = curline;
  742.       int    savec = curchar;
  743. !     extern disk_line    f_getputl();
  744.   
  745.       strcpy(end, linebuf + curchar);
  746.       xeof = f_gets(fp, linebuf + curchar, LBSIZE - curchar);
  747. ***************
  748. *** 157,169 ****
  749.   #ifndef CHDIR
  750.   
  751.   char *
  752. ! pr_name(fname)
  753.   char    *fname;
  754.   {
  755.       if (fname == 0)
  756.           return 0;
  757.   
  758. !     if (strncmp(fname, HomeDir, HomeLen) == 0) {
  759.           static char    name_buf[100];
  760.   
  761.           sprintf(name_buf, "~%s", fname + HomeLen);
  762. --- 159,171 ----
  763.   #ifndef CHDIR
  764.   
  765.   char *
  766. ! pr_name(fname, okay_home)
  767.   char    *fname;
  768.   {
  769.       if (fname == 0)
  770.           return 0;
  771.   
  772. !     if (okay_home == YES && strncmp(fname, HomeDir, HomeLen) == 0) {
  773.           static char    name_buf[100];
  774.   
  775.           sprintf(name_buf, "~%s", fname + HomeLen);
  776. ***************
  777. *** 188,194 ****
  778.   }
  779.   
  780.   char *
  781. ! pr_name(fname)
  782.   char    *fname;
  783.   {
  784.       int    n;
  785. --- 190,196 ----
  786.   }
  787.   
  788.   char *
  789. ! pr_name(fname, okay_home)
  790.   char    *fname;
  791.   {
  792.       int    n;
  793. ***************
  794. *** 201,207 ****
  795.           (fname[n] == '/'))
  796.           return fname + n + 1;
  797.   
  798. !     if (strcmp(HomeDir, "/") != 0 && strncmp(fname, HomeDir, HomeLen) == 0) {
  799.           static char    name_buf[100];
  800.   
  801.           sprintf(name_buf, "~%s", fname + HomeLen);
  802. --- 203,209 ----
  803.           (fname[n] == '/'))
  804.           return fname + n + 1;
  805.   
  806. !     if (okay_home == YES && strcmp(HomeDir, "/") != 0 && strncmp(fname, HomeDir, HomeLen) == 0) {
  807.           static char    name_buf[100];
  808.   
  809.           sprintf(name_buf, "~%s", fname + HomeLen);
  810. ***************
  811. *** 256,268 ****
  812.   
  813.   getCWD()
  814.   {
  815. !     char    *cwd = getenv("CWD");
  816.   #ifdef JOB_CONTROL
  817.       extern char    *getwd();
  818.       char    pathname[FILESIZE];
  819.   #endif
  820.   
  821.       if (cwd == 0)
  822.   #ifdef JOB_CONTROL
  823.           cwd = getwd(pathname);
  824.   #else
  825. --- 258,273 ----
  826.   
  827.   getCWD()
  828.   {
  829. !     char    *cwd;
  830.   #ifdef JOB_CONTROL
  831.       extern char    *getwd();
  832.       char    pathname[FILESIZE];
  833.   #endif
  834.   
  835. +     cwd = getenv("CWD");
  836.       if (cwd == 0)
  837. +         cwd = getenv("PWD");
  838. +     if (cwd == 0)
  839.   #ifdef JOB_CONTROL
  840.           cwd = getwd(pathname);
  841.   #else
  842. ***************
  843. *** 278,284 ****
  844.   
  845.       s_mess(": %f ");
  846.       for (i = DirSP; i >= 0; i--)
  847. !         add_mess("%s ", pr_name(DirStack[i]));
  848.   }
  849.   
  850.   prCWD()
  851. --- 283,289 ----
  852.   
  853.       s_mess(": %f ");
  854.       for (i = DirSP; i >= 0; i--)
  855. !         add_mess("%s ", pr_name(DirStack[i], YES));
  856.   }
  857.   
  858.   prCWD()
  859. ***************
  860. *** 339,344 ****
  861. --- 344,350 ----
  862.       return offset;
  863.   }
  864.   
  865. + private
  866.   dfollow(file, into)
  867.   char    *file,
  868.       *into;
  869. ***************
  870. *** 377,382 ****
  871. --- 383,389 ----
  872.   
  873.   #endif CHDIR
  874.   
  875. + private
  876.   get_hdir(user, buf)
  877.   register char    *user,
  878.           *buf;
  879. ***************
  880. *** 453,464 ****
  881.   
  882.   WrtReg()
  883.   {
  884. !     DoWriteReg(0);
  885.   }
  886.   
  887.   AppReg()
  888.   {
  889. !     DoWriteReg(1);
  890.   }
  891.   
  892.   int    CreatMode = DFLT_MODE;
  893. --- 460,471 ----
  894.   
  895.   WrtReg()
  896.   {
  897. !     DoWriteReg(NO);
  898.   }
  899.   
  900.   AppReg()
  901.   {
  902. !     DoWriteReg(YES);
  903.   }
  904.   
  905.   int    CreatMode = DFLT_MODE;
  906. ***************
  907. *** 474,480 ****
  908.       fname = ask_file((char *) 0, (char *) 0, fnamebuf);
  909.   
  910.   #ifdef BACKUPFILES
  911. !     if (!app) {
  912.           filemunge(fname);
  913.   
  914.           if (BkupOnWrite)
  915. --- 481,487 ----
  916.       fname = ask_file((char *) 0, (char *) 0, fnamebuf);
  917.   
  918.   #ifdef BACKUPFILES
  919. !     if (app == NO) {
  920.           filemunge(fname);
  921.   
  922.           if (BkupOnWrite)
  923. ***************
  924. *** 511,522 ****
  925.   
  926.       chk_mtime(curbuf, fname, "write");
  927.       filemunge(fname);
  928. !     curbuf->b_type = B_FILE;      /* In case it wasn't before. */
  929.       setfname(curbuf, fname);
  930.       file_write(fname, 0);
  931.       unmodify();
  932.   }
  933.   
  934.   File *
  935.   open_file(fname, buf, how, ifbad, loudness)
  936.   register char    *fname;
  937. --- 518,545 ----
  938.   
  939.       chk_mtime(curbuf, fname, "write");
  940.       filemunge(fname);
  941. !     curbuf->b_type = B_FILE;      /* in case it wasn't before */
  942.       setfname(curbuf, fname);
  943.       file_write(fname, 0);
  944.       unmodify();
  945.   }
  946.   
  947. + /* Open file FNAME supplying the buffer IO routine with buffer BUF.
  948. +    HOW is F_READ, F_WRITE or F_APPEND.  IFBAD == COMPLAIN means that
  949. +    if we fail at opening the file, call complain.  LOUDNESS says
  950. +    whether or not to print the "reading ..." message on the message
  951. +    line.
  952. +    NOTE:  This opens the pr_name(fname, NO) of fname.  That is, FNAME
  953. +       is usually an entire pathname, which can be slow when the
  954. +       pathname is long and there are lots of symbolic links along
  955. +       the way (which has become very common in my experience).  So,
  956. +       this speeds up opens file names in the local directory.  It
  957. +       will not speed up things like "../scm/foo.scm" simple because
  958. +       by the time we get here that's already been expanded to an
  959. +       absolute pathname.  But this is a start.
  960. +    */
  961.   File *
  962.   open_file(fname, buf, how, ifbad, loudness)
  963.   register char    *fname;
  964. ***************
  965. *** 529,535 ****
  966.       io_lines = 0;
  967.       tellall = loudness;
  968.   
  969. !     fp = f_open(fname, how, buf, LBSIZE);
  970.       if (fp == NIL) {
  971.                   message(IOerr((how == F_READ) ? "open" : "create", fname));
  972.           if (ifbad == COMPLAIN)
  973. --- 552,558 ----
  974.       io_lines = 0;
  975.       tellall = loudness;
  976.   
  977. !     fp = f_open(pr_name(fname, NO), how, buf, LBSIZE);
  978.       if (fp == NIL) {
  979.                   message(IOerr((how == F_READ) ? "open" : "create", fname));
  980.           if (ifbad == COMPLAIN)
  981. ***************
  982. *** 537,547 ****
  983.       } else {
  984.           int    readonly = FALSE;
  985.   
  986. !         if (access(fname, W_OK) == -1 && errno != ENOENT)
  987.               readonly = TRUE;
  988.                                
  989.           if (loudness != QUIET)
  990. !             f_mess("\"%s\"%s", pr_name(fname),
  991.                      readonly ? " [Read only]" : NullStr);
  992.       }
  993.       return fp;
  994. --- 560,570 ----
  995.       } else {
  996.           int    readonly = FALSE;
  997.   
  998. !         if (access(pr_name(fname, NO), W_OK) == -1 && errno != ENOENT)
  999.               readonly = TRUE;
  1000.                                
  1001.           if (loudness != QUIET)
  1002. !             f_mess("\"%s\"%s", pr_name(fname, YES),
  1003.                      readonly ? " [Read only]" : NullStr);
  1004.       }
  1005.       return fp;
  1006. ***************
  1007. *** 552,559 ****
  1008.      doing.
  1009.   
  1010.      I hate to use another stat(), but to use confirm we gotta
  1011. !    do this before we open the file. */
  1012.   
  1013.   chk_mtime(thisbuf, fname, how)
  1014.   Buffer    *thisbuf;
  1015.   char    *fname,
  1016. --- 575,586 ----
  1017.      doing.
  1018.   
  1019.      I hate to use another stat(), but to use confirm we gotta
  1020. !    do this before we open the file.
  1021.   
  1022. +    NOTE: This stats FNAME after converting it to a path-relative
  1023. +      name.  I can't see why this would cause a problem ...
  1024. +    */
  1025.   chk_mtime(thisbuf, fname, how)
  1026.   Buffer    *thisbuf;
  1027.   char    *fname,
  1028. ***************
  1029. *** 566,577 ****
  1030.       if ((thisbuf->b_mtime != 0) &&        /* if we care ... */
  1031.           (b = file_exists(fname)) &&        /* we already have this file */
  1032.           (b == thisbuf) &&            /* and it's the current buffer */
  1033. !         (stat(fname, &stbuf) != -1) &&    /* and we can stat it */
  1034.           (stbuf.st_mtime != b->b_mtime)) {    /* and there's trouble. */
  1035.               rbell();
  1036.           redisplay();    /* Ring that bell! */
  1037.               TOstart("Warning", TRUE);
  1038. !             Typeout("\"%s\" now saved on disk is not what you last", pr_name(fname));
  1039.           Typeout("visited or saved.  Probably someone else is editing");
  1040.           Typeout("your file at the same time.");
  1041.               if (how) {
  1042. --- 593,604 ----
  1043.       if ((thisbuf->b_mtime != 0) &&        /* if we care ... */
  1044.           (b = file_exists(fname)) &&        /* we already have this file */
  1045.           (b == thisbuf) &&            /* and it's the current buffer */
  1046. !         (stat(pr_name(fname, NO), &stbuf) != -1) &&    /* and we can stat it */
  1047.           (stbuf.st_mtime != b->b_mtime)) {    /* and there's trouble. */
  1048.               rbell();
  1049.           redisplay();    /* Ring that bell! */
  1050.               TOstart("Warning", TRUE);
  1051. !             Typeout("\"%s\" now saved on disk is not what you last", pr_name(fname, YES));
  1052.           Typeout("visited or saved.  Probably someone else is editing");
  1053.           Typeout("your file at the same time.");
  1054.               if (how) {
  1055. ***************
  1056. *** 626,632 ****
  1057.           for (;;) {
  1058.               rbell();
  1059.               y_or_n = ask(NullStr, "Shall I make your changes to \"%s\" permanent? ", curbuf->b_name);
  1060. !             c = Upper(*y_or_n);
  1061.               if (c == 'Y' || c == 'N')
  1062.                   break;
  1063.           }            
  1064. --- 653,659 ----
  1065.           for (;;) {
  1066.               rbell();
  1067.               y_or_n = ask(NullStr, "Shall I make your changes to \"%s\" permanent? ", curbuf->b_name);
  1068. !             c = CharUpcase(*y_or_n);
  1069.               if (c == 'Y' || c == 'N')
  1070.                   break;
  1071.           }            
  1072. ***************
  1073. *** 658,664 ****
  1074.   
  1075.   private int    nleft,    /* number of good characters left in current block */
  1076.           tmpfd = -1;
  1077. ! private disk_line    DFree = 1;
  1078.               /* pointer to end of tmp file */
  1079.   private char    *tfname;
  1080.   
  1081. --- 685,691 ----
  1082.   
  1083.   private int    nleft,    /* number of good characters left in current block */
  1084.           tmpfd = -1;
  1085. ! disk_line    DFree = 1;
  1086.               /* pointer to end of tmp file */
  1087.   private char    *tfname;
  1088.   
  1089. ***************
  1090. *** 682,691 ****
  1091.       (void) unlink(tfname);
  1092.   }
  1093.   
  1094. ! /* Get a line at `tl' in the tmp file into `buf' which should be LBSIZE
  1095. !    long. */
  1096.   
  1097. ! int    Jr_Len;        /* Length of Just Read Line. */
  1098.   private char    *getblock();
  1099.   
  1100.   getline(addr, buf)
  1101. --- 709,718 ----
  1102.       (void) unlink(tfname);
  1103.   }
  1104.   
  1105. ! /* get a line at `tl' in the tmp file into `buf' which should be LBSIZE
  1106. !    long */
  1107.   
  1108. ! int    Jr_Len;        /* length of Just Read Line */
  1109.   private char    *getblock();
  1110.   
  1111.   getline(addr, buf)
  1112. diff -c ojove/iproc-pipes.c jove/iproc-pipes.c
  1113. *** ojove/iproc-pipes.c    Thu Jul 16 09:14:30 1987
  1114. --- jove/iproc-pipes.c    Thu Jun 25 10:02:30 1987
  1115. ***************
  1116. *** 13,20 ****
  1117.   #include <signal.h>
  1118.   #include <sgtty.h>
  1119.   
  1120. - typedef struct process    Process;
  1121.   #define DEAD    1    /* Dead but haven't informed user yet */
  1122.   #define STOPPED    2    /* Job stopped */
  1123.   #define RUNNING    3    /* Just running */
  1124. --- 13,18 ----
  1125. ***************
  1126. *** 25,30 ****
  1127. --- 23,29 ----
  1128.   #define KILLED    2
  1129.   
  1130.   #define isdead(p)    (p == 0 || proc_state(p) == DEAD || p->p_toproc == -1)
  1131. + #define makedead(p)    (proc_state(p) = DEAD)
  1132.   
  1133.   #define proc_buf(p)    (p->p_buffer->b_name)
  1134.   #define proc_cmd(p)    (p->p_name)
  1135. ***************
  1136. *** 36,42 ****
  1137.       ProcOutput,
  1138.       NumProcs = 0;
  1139.   
  1140. ! static char *
  1141.   pstate(p)
  1142.   Process    *p;
  1143.   {
  1144. --- 35,41 ----
  1145.       ProcOutput,
  1146.       NumProcs = 0;
  1147.   
  1148. ! char *
  1149.   pstate(p)
  1150.   Process    *p;
  1151.   {
  1152. ***************
  1153. *** 54,65 ****
  1154.           if (p->p_howdied == EXITED) {
  1155.               if (p->p_reason == 0)
  1156.                   return "Done";
  1157. !             return sprint("[Exit %d]", p->p_reason);
  1158.           }
  1159. !         return sprint("[Killed %d]", p->p_reason);
  1160.   
  1161.       default:
  1162. !         return "Unknown state.";
  1163.       }
  1164.   }
  1165.   
  1166. --- 53,64 ----
  1167.           if (p->p_howdied == EXITED) {
  1168.               if (p->p_reason == 0)
  1169.                   return "Done";
  1170. !             return sprint("Exit %d", p->p_reason);
  1171.           }
  1172. !         return sprint("Killed %d", p->p_reason);
  1173.   
  1174.       default:
  1175. !         return "Unknown state";
  1176.       }
  1177.   }
  1178.   
  1179. ***************
  1180. *** 98,104 ****
  1181.               finish(1);
  1182.           read_proc(header.pid, header.nbytes);
  1183.       }
  1184. -     redisplay();
  1185.       here = 0;
  1186.       sigrelse(SIGCHLD);
  1187.   }
  1188. --- 97,102 ----
  1189. ***************
  1190. *** 126,132 ****
  1191.       }
  1192.   
  1193.       if (nbytes == EOF) {        /* Okay to clean up this process */
  1194. !         p->p_eof = 1;
  1195.           NumProcs--;    /* As far as getch() in main is concerned */
  1196.           return;
  1197.       }
  1198. --- 124,130 ----
  1199.       }
  1200.   
  1201.       if (nbytes == EOF) {        /* Okay to clean up this process */
  1202. !         proc_close(p);
  1203.           NumProcs--;    /* As far as getch() in main is concerned */
  1204.           return;
  1205.       }
  1206. ***************
  1207. *** 155,166 ****
  1208.       proc_kill(curbuf->b_process, SIGQUIT);
  1209.   }
  1210.   
  1211. ! static
  1212.   proc_close(p)
  1213.   Process    *p;
  1214.   {
  1215.       (void) close(p->p_toproc);
  1216. !     p->p_toproc = -1;    /* Writes will fail. */
  1217.   }
  1218.   
  1219.   do_rtp(mp)
  1220. --- 153,164 ----
  1221.       proc_kill(curbuf->b_process, SIGQUIT);
  1222.   }
  1223.   
  1224. ! private
  1225.   proc_close(p)
  1226.   Process    *p;
  1227.   {
  1228.       (void) close(p->p_toproc);
  1229. !     p->p_toproc = -1;    /* writes will fail */
  1230.   }
  1231.   
  1232.   do_rtp(mp)
  1233. ***************
  1234. *** 228,234 ****
  1235.           (void) dup2(ProcOutput, 1);
  1236.           (void) dup2(ProcOutput, 2);
  1237.           pclose(toproc);
  1238. !         execv(Portsrv, args);
  1239.           printf("Execl failed.\n");
  1240.           _exit(1);
  1241.       }
  1242. --- 226,232 ----
  1243.           (void) dup2(ProcOutput, 1);
  1244.           (void) dup2(ProcOutput, 2);
  1245.           pclose(toproc);
  1246. !         execv(Portsrv, argv);
  1247.           printf("Execl failed.\n");
  1248.           _exit(1);
  1249.       }
  1250. ***************
  1251. *** 260,270 ****
  1252.       /* Pop_wind() after everything is set up; important!
  1253.          Bindings won't work right unless newbuf->b_process is already
  1254.          set up BEFORE NEWBUF is first SetBuf()'d. */
  1255. !     newp->p_mark = MakeMark(curline, curchar, FLOATER);
  1256.   
  1257.       newp->p_toproc = toproc[1];
  1258.       newp->p_reason = 0;
  1259. -     newp->p_eof = 0;
  1260.       NumProcs++;
  1261.       (void) close(toproc[0]);
  1262.       sigrelse(SIGCHLD);
  1263. --- 258,267 ----
  1264.       /* Pop_wind() after everything is set up; important!
  1265.          Bindings won't work right unless newbuf->b_process is already
  1266.          set up BEFORE NEWBUF is first SetBuf()'d. */
  1267. !     newp->p_mark = MakeMark(curline, curchar, M_FLOATER);
  1268.   
  1269.       newp->p_toproc = toproc[1];
  1270.       newp->p_reason = 0;
  1271.       NumProcs++;
  1272.       (void) close(toproc[0]);
  1273.       sigrelse(SIGCHLD);
  1274. diff -c ojove/iproc-ptys.c jove/iproc-ptys.c
  1275. *** ojove/iproc-ptys.c    Thu Jul 16 09:14:31 1987
  1276. --- jove/iproc-ptys.c    Thu Jun 25 10:01:44 1987
  1277. ***************
  1278. *** 12,17 ****
  1279. --- 12,18 ----
  1280.   #endif
  1281.   #include <signal.h>
  1282.   #include <sgtty.h>
  1283. + #include <errno.h>
  1284.   
  1285.   #define DEAD    1    /* Dead but haven't informed user yet */
  1286.   #define STOPPED    2    /* Job stopped */
  1287. ***************
  1288. *** 23,28 ****
  1289. --- 24,30 ----
  1290.   #define KILLED    2
  1291.   
  1292.   #define isdead(p)    (p == 0 || proc_state(p) == DEAD || p->p_fd == -1)
  1293. + #define makedead(p)    (proc_state(p) = DEAD)
  1294.   
  1295.   #define proc_buf(p)    (p->p_buffer->b_name)
  1296.   #define proc_cmd(p)    (p->p_name)
  1297. ***************
  1298. *** 45,51 ****
  1299.       extern struct ltchars ls1;
  1300.   #endif
  1301.   
  1302. ! static char *
  1303.   pstate(p)
  1304.   Process    *p;
  1305.   {
  1306. --- 47,53 ----
  1307.       extern struct ltchars ls1;
  1308.   #endif
  1309.   
  1310. ! char *
  1311.   pstate(p)
  1312.   Process    *p;
  1313.   {
  1314. ***************
  1315. *** 60,71 ****
  1316.           if (p->p_howdied == EXITED) {
  1317.               if (p->p_reason == 0)
  1318.                   return "Done";
  1319. !             return sprint("exit(%d)", p->p_reason);
  1320.           }
  1321. !         return sprint("Killed(%d)", p->p_reason);
  1322.   
  1323.       default:
  1324. !         return "Unknown state.";
  1325.       }
  1326.   }
  1327.   
  1328. --- 62,73 ----
  1329.           if (p->p_howdied == EXITED) {
  1330.               if (p->p_reason == 0)
  1331.                   return "Done";
  1332. !             return sprint("Exit %d", p->p_reason);
  1333.           }
  1334. !         return sprint("Killed %d", p->p_reason);
  1335.   
  1336.       default:
  1337. !         return "Unknown state";
  1338.       }
  1339.   }
  1340.   
  1341. ***************
  1342. *** 98,111 ****
  1343.       }
  1344.   
  1345.       n = read(fd, ibuf, sizeof(ibuf) - 1);
  1346. !     if (n == 0) {
  1347. !         proc_close(p);
  1348. !         NumProcs--;
  1349.           return;
  1350.       }
  1351.       ibuf[n] = '\0';
  1352.       proc_rec(p, ibuf);
  1353. -     redisplay();
  1354.   }
  1355.   
  1356.   ProcKill()
  1357. --- 100,123 ----
  1358.       }
  1359.   
  1360.       n = read(fd, ibuf, sizeof(ibuf) - 1);
  1361. !     /* NOTE: This read somethings returns -1 when it's the first time
  1362. !        we're reading the socket.  Errno was set to I/O error or something
  1363. !        bizarre like that.  So, I'm choosing to ignore this.  I ignored
  1364. !        it before, and what happened was random text was being inserted
  1365. !        at the beginning of the buffer because the ibuf[n] = '\0' wasn't
  1366. !         working right (ibuf[-1] = '\0'). */
  1367. !     if (n == -1 && errno == EIO)
  1368.           return;
  1369. +     if (n <= 0) {
  1370. +         if (n == 0) {
  1371. +             makedead(p);
  1372. +             return;
  1373. +         }
  1374. +         sprintf(ibuf, "\n[pty read error: %d]\n", errno);
  1375. +         n = strlen(ibuf);
  1376.       }
  1377.       ibuf[n] = '\0';
  1378.       proc_rec(p, ibuf);
  1379.   }
  1380.   
  1381.   ProcKill()
  1382. ***************
  1383. *** 171,183 ****
  1384.       (void) write(p->p_fd, &c, 1);
  1385.   }
  1386.   
  1387. ! static
  1388.   proc_close(p)
  1389.   Process *p;
  1390.   {
  1391.       (void) close(p->p_fd);
  1392.       global_fd &= ~(1 << p->p_fd);
  1393. -     p->p_eof++;
  1394.   }
  1395.   
  1396.   do_rtp(mp)
  1397. --- 183,194 ----
  1398.       (void) write(p->p_fd, &c, 1);
  1399.   }
  1400.   
  1401. ! private
  1402.   proc_close(p)
  1403.   Process *p;
  1404.   {
  1405.       (void) close(p->p_fd);
  1406.       global_fd &= ~(1 << p->p_fd);
  1407.   }
  1408.   
  1409.   do_rtp(mp)
  1410. ***************
  1411. *** 216,222 ****
  1412.       va_list    ap;
  1413.       char    *argv[32],
  1414.           *cp;
  1415. !     Window *owind    = curwind;
  1416.       int    pid;
  1417.       Process    *newp;
  1418.       Buffer     *newbuf;
  1419. --- 227,233 ----
  1420.       va_list    ap;
  1421.       char    *argv[32],
  1422.           *cp;
  1423. !     Window *owind = curwind;
  1424.       int    pid;
  1425.       Process    *newp;
  1426.       Buffer     *newbuf;
  1427. ***************
  1428. *** 348,354 ****
  1429.   
  1430.       newp->p_fd = ttyfd;
  1431.       newp->p_pid = pid;
  1432. -     newp->p_eof = 0;
  1433.   
  1434.       newbuf = do_select((Window *) 0, bufname);
  1435.       newbuf->b_type = B_PROCESS;
  1436. --- 359,364 ----
  1437. ***************
  1438. *** 371,377 ****
  1439.       newp->p_name = copystr(cmdbuf);
  1440.       newp->p_state = RUNNING;
  1441.       newp->p_reason = 0;
  1442. !     newp->p_mark = MakeMark(curline, curchar, FLOATER);
  1443.   
  1444.       newp->p_next = procs;
  1445.       procs = newp;
  1446. --- 381,387 ----
  1447.       newp->p_name = copystr(cmdbuf);
  1448.       newp->p_state = RUNNING;
  1449.       newp->p_reason = 0;
  1450. !     newp->p_mark = MakeMark(curline, curchar, M_FLOATER);
  1451.   
  1452.       newp->p_next = procs;
  1453.       procs = newp;
  1454. diff -c ojove/iproc.c jove/iproc.c
  1455. *** ojove/iproc.c    Thu Jul 16 09:14:32 1987
  1456. --- jove/iproc.c    Wed Jun 24 12:52:13 1987
  1457. ***************
  1458. *** 30,36 ****
  1459.           if (!isdead(p)) {
  1460.               if (killem == -1) {
  1461.                   yorn = ask("y", "Should I kill your i-processes? ");
  1462. !                 killem = (Upper(*yorn) == 'Y');
  1463.               }
  1464.               if (killem)
  1465.                   proc_kill(p, SIGKILL);
  1466. --- 30,36 ----
  1467.           if (!isdead(p)) {
  1468.               if (killem == -1) {
  1469.                   yorn = ask("y", "Should I kill your i-processes? ");
  1470. !                 killem = (CharUpcase(*yorn) == 'Y');
  1471.               }
  1472.               if (killem)
  1473.                   proc_kill(p, SIGKILL);
  1474. ***************
  1475. *** 50,56 ****
  1476.   /* Process receive: receives the characters in buf, and appends them to
  1477.      the buffer associated with p. */
  1478.   
  1479. ! static
  1480.   proc_rec(p, buf)
  1481.   register Process    *p;
  1482.   char    *buf;
  1483. --- 50,56 ----
  1484.   /* Process receive: receives the characters in buf, and appends them to
  1485.      the buffer associated with p. */
  1486.   
  1487. ! private
  1488.   proc_rec(p, buf)
  1489.   register Process    *p;
  1490.   char    *buf;
  1491. ***************
  1492. *** 68,88 ****
  1493.       if (w != 0)
  1494.           do_disp = (in_window(w, p->p_mark->m_line) != -1);
  1495.       SetBuf(p->p_buffer);
  1496. !     savepoint = MakeMark(curline, curchar, FLOATER);
  1497. !     ToMark(p->p_mark);    /* Where output last stopped. */
  1498.       if (savepoint->m_line == curline && savepoint->m_char == curchar)
  1499.           sameplace++;
  1500.   
  1501.       ins_str(buf, YES);
  1502.       if (do_disp) {
  1503.           w->w_line = curline;
  1504.           w->w_char = curchar;
  1505.           redisplay();
  1506.       }
  1507. -     MarkSet(p->p_mark, curline, curchar);
  1508. -     if (!sameplace)
  1509. -         ToMark(savepoint);    /* Back to where we were. */
  1510. -     DelMark(savepoint);
  1511.       SetBuf(saveb);
  1512.   }
  1513.   
  1514. --- 68,91 ----
  1515.       if (w != 0)
  1516.           do_disp = (in_window(w, p->p_mark->m_line) != -1);
  1517.       SetBuf(p->p_buffer);
  1518. !     savepoint = MakeMark(curline, curchar, M_FLOATER);
  1519. !     ToMark(p->p_mark);        /* where output last stopped */
  1520.       if (savepoint->m_line == curline && savepoint->m_char == curchar)
  1521.           sameplace++;
  1522.   
  1523.       ins_str(buf, YES);
  1524. +     MarkSet(p->p_mark, curline, curchar);
  1525. +     if (!sameplace)
  1526. +         ToMark(savepoint);    /* back to where we were */
  1527. +     DelMark(savepoint);
  1528. +     /* redisplay now, instead of right after the ins_str, so that
  1529. +        we don't get a bouncing effect if point is not the same as
  1530. +        the process output position */
  1531.       if (do_disp) {
  1532.           w->w_line = curline;
  1533.           w->w_char = curchar;
  1534.           redisplay();
  1535.       }
  1536.       SetBuf(saveb);
  1537.   }
  1538.   
  1539. ***************
  1540. *** 95,105 ****
  1541.           s_mess("Cannot kill %s!", proc_buf(p));
  1542.   }
  1543.   
  1544. ! /* Deal with a process' death.  proc_rec turns on the FREEUP bit when it
  1545. !    it gets the "EOF" from portsrv.  FREEUP'd processes get unlinked from
  1546. !    the list, and the proc stucture and proc_buf(p) get free'd up, here. */
  1547.   
  1548. - private
  1549.   DealWDeath()
  1550.   {
  1551.       register Process    *p,
  1552. --- 98,107 ----
  1553.           s_mess("Cannot kill %s!", proc_buf(p));
  1554.   }
  1555.   
  1556. ! /* Deal with a process' death.  Go through all processes and find
  1557. !    the ones which have gotten EOF.  Delete them from the list and
  1558. !    free up the memory, and insert a status string. */
  1559.   
  1560.   DealWDeath()
  1561.   {
  1562.       register Process    *p,
  1563. ***************
  1564. *** 108,114 ****
  1565.       
  1566.       for (p = procs; p != 0; p = next) {
  1567.           next = p->p_next;
  1568. !         if (!p->p_eof) {
  1569.               prev = p;
  1570.               continue;
  1571.           }
  1572. --- 110,116 ----
  1573.       
  1574.       for (p = procs; p != 0; p = next) {
  1575.           next = p->p_next;
  1576. !         if (p->p_state != DEAD) {
  1577.               prev = p;
  1578.               continue;
  1579.           }
  1580. ***************
  1581. *** 130,135 ****
  1582. --- 132,138 ----
  1583.       char    *fmt = "%-15s  %-15s  %-8s %s",
  1584.           pidstr[10];
  1585.   
  1586. +     DealWDeath();
  1587.       if (procs == 0) {
  1588.           message("[No subprocesses]");
  1589.           return;
  1590. ***************
  1591. *** 142,148 ****
  1592.           sprintf(pidstr, "%d", p->p_pid);
  1593.           Typeout(fmt, proc_buf(p), pstate(p), pidstr, p->p_name);
  1594.       }
  1595. -     DealWDeath();
  1596.       TOstop();
  1597.   }
  1598.   
  1599. --- 145,150 ----
  1600. ***************
  1601. *** 160,168 ****
  1602. --- 162,193 ----
  1603.   SendData(newlinep)
  1604.   {
  1605.       register Process    *p = curbuf->b_process;
  1606. +     register char    *lp,
  1607. +             *gp;    /* JF fix for better prompt handling */
  1608.   
  1609.       if (isdead(p))
  1610.           return;
  1611. +     /* If the process mark was involved in a big deletion, because
  1612. +        the user hit ^W or something, then let's do some magic with
  1613. +        the process mark.  Problem is that if the user yanks back the
  1614. +        text he deleted, the mark stays at the beginning of the region,
  1615. +        and so the next time SendData() is called the entire region
  1616. +        will be sent.  That's not good.  So, to deal with that we reset
  1617. +        the mark to the last line, after skipping over the prompt, etc. */
  1618. +     if (p->p_mark->m_flags & M_BIG_DELETE) {
  1619. +         Bufpos    bp;
  1620. +         p->p_mark->m_flags &= ~M_BIG_DELETE;
  1621. +         DOTsave(&bp);
  1622. +         ToLast();
  1623. +         Bol();
  1624. +         while (LookingAt(proc_prompt, linebuf, curchar))
  1625. +             SetDot(dosearch(proc_prompt, 1, 1));
  1626. +         MarkSet(p->p_mark, curline, curchar);
  1627. +         SetDot(&bp);
  1628. +     }
  1629.       if (lastp(curline)) {
  1630.           Eol();
  1631.           if (newlinep)
  1632. ***************
  1633. *** 174,181 ****
  1634.           while (LookingAt(proc_prompt, linebuf, curchar))
  1635.               SetDot(dosearch(proc_prompt, 1, 1));
  1636.           strcpy(genbuf, linebuf + curchar);
  1637. !         ToLast();
  1638. !         ins_str(genbuf, NO);
  1639.       }
  1640.   }
  1641.   
  1642. --- 199,210 ----
  1643.           while (LookingAt(proc_prompt, linebuf, curchar))
  1644.               SetDot(dosearch(proc_prompt, 1, 1));
  1645.           strcpy(genbuf, linebuf + curchar);
  1646. !         Eof();
  1647. !         gp = genbuf;
  1648. !         lp = linebuf;
  1649. !         while (*lp == *gp && *lp != '\0')
  1650. !             lp++, gp++;
  1651. !         ins_str(gp, NO);
  1652.       }
  1653.   }
  1654.   
  1655. ***************
  1656. *** 222,233 ****
  1657.   register int    pid;
  1658.   union wait    w;
  1659.   {
  1660. -     char    str[128];
  1661.       register Process    *child;
  1662.   
  1663.       if ((child = proc_pid(pid)) == 0)
  1664.           return;
  1665.   
  1666.       if (WIFSTOPPED(w))
  1667.           child->p_state = STOPPED;
  1668.       else {
  1669. --- 251,262 ----
  1670.   register int    pid;
  1671.   union wait    w;
  1672.   {
  1673.       register Process    *child;
  1674.   
  1675.       if ((child = proc_pid(pid)) == 0)
  1676.           return;
  1677.   
  1678. +     UpdModLine = YES;        /* we're changing state ... */
  1679.       if (WIFSTOPPED(w))
  1680.           child->p_state = STOPPED;
  1681.       else {
  1682. ***************
  1683. *** 238,249 ****
  1684.               child->p_reason = w.w_termsig;
  1685.               child->p_howdied = KILLED;
  1686.           }
  1687. !         proc_close(child);
  1688.       }
  1689. -     sprintf(str, "[Process %s: %s]\n",
  1690. -         proc_cmd(child),
  1691. -         pstate(child));
  1692. -     proc_rec(child, str);
  1693.   }
  1694.   
  1695.   /* Push/pod process bindings.  I openly acknowledge that this is a
  1696. --- 267,286 ----
  1697.               child->p_reason = w.w_termsig;
  1698.               child->p_howdied = KILLED;
  1699.           }
  1700. !         {
  1701. !             Buffer    *save = curbuf;
  1702. !             char    mesg[128];
  1703. !             /* insert status message now */
  1704. !             sprintf(mesg, "[Process %s: %s]\n",
  1705. !                 proc_cmd(child),
  1706. !                 pstate(child));
  1707. !             SetBuf(child->p_buffer);
  1708. !             ins_str(mesg, NO);
  1709. !             SetBuf(save);
  1710. !             redisplay();
  1711. !         }
  1712.       }
  1713.   }
  1714.   
  1715.   /* Push/pod process bindings.  I openly acknowledge that this is a
  1716. diff -c ojove/jove.c jove/jove.c
  1717. *** ojove/jove.c    Thu Jul 16 09:14:35 1987
  1718. --- jove/jove.c    Fri Jul 10 09:25:50 1987
  1719. ***************
  1720. *** 20,27 ****
  1721.   #include <sgtty.h>
  1722.   #else
  1723.   #include <termio.h>
  1724. - #endif SYSV
  1725.   #include <fcntl.h>
  1726.   
  1727.   #ifdef TIOCSLTC
  1728.   struct ltchars    ls1,
  1729. --- 20,27 ----
  1730.   #include <sgtty.h>
  1731.   #else
  1732.   #include <termio.h>
  1733.   #include <fcntl.h>
  1734. + #endif SYSV
  1735.   
  1736.   #ifdef TIOCSLTC
  1737.   struct ltchars    ls1,
  1738. ***************
  1739. *** 62,71 ****
  1740.       int    CoreDump = (code != 0 && code != SIGHUP),
  1741.           DelTmps = 1;        /* Usually we delete them. */
  1742.   
  1743. - #ifdef LSRHS
  1744. -     if (CoreDump)
  1745. -         setdump(1);
  1746. - #endif
  1747.       if (code == SIGINT) {
  1748.           char    c;
  1749.   
  1750. --- 62,67 ----
  1751. ***************
  1752. *** 106,114 ****
  1753.       if (CoreDump)
  1754.           abort();
  1755.   #ifdef PROFILING
  1756. !     exit(exp_p);
  1757.   #else
  1758. !     _exit(exp_p);
  1759.   #endif
  1760.   }
  1761.   
  1762. --- 102,110 ----
  1763.       if (CoreDump)
  1764.           abort();
  1765.   #ifdef PROFILING
  1766. !     exit(0);
  1767.   #else
  1768. !     _exit(0);
  1769.   #endif
  1770.   }
  1771.   
  1772. ***************
  1773. *** 137,143 ****
  1774.       }
  1775.       if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
  1776.       finish(SIGHUP);
  1777. -     return;
  1778.   }
  1779.   #endif SYSV
  1780.   
  1781. --- 133,138 ----
  1782. ***************
  1783. *** 399,405 ****
  1784.   }
  1785.   
  1786.   int    OKXonXoff = 0,        /* ^S and ^Q initially DON'T work */
  1787. !     IntChar = CTL(]);
  1788.   
  1789.   ttsize()
  1790.   {
  1791. --- 394,400 ----
  1792.   }
  1793.   
  1794.   int    OKXonXoff = 0,        /* ^S and ^Q initially DON'T work */
  1795. !     IntChar = CTL(']');
  1796.   
  1797.   ttsize()
  1798.   {
  1799. ***************
  1800. *** 500,505 ****
  1801. --- 495,502 ----
  1802.       TABS = !((sg1.c_oflag & TAB3) == TAB3);
  1803.       ospeed = sg1.c_cflag & CBAUD;
  1804.   
  1805. +     if (OKXonXoff)
  1806. +         sg2.c_iflag &= ~(IXON | IXOFF);
  1807.       sg2.c_iflag &= ~(INLCR|ICRNL|IGNCR);
  1808.       sg2.c_lflag &= ~(ISIG|ICANON|ECHO);
  1809.       sg2.c_oflag &= ~(OCRNL|ONLCR);
  1810. ***************
  1811. *** 584,591 ****
  1812.   
  1813.       if (cp == 0) {
  1814.           rbell();
  1815. !         exp = 1;
  1816. !         exp_p = errormsg = NO;
  1817.           message(NullStr);
  1818.       } else
  1819.           ExecCmd(cp);
  1820. --- 581,588 ----
  1821.   
  1822.       if (cp == 0) {
  1823.           rbell();
  1824. !         clr_arg_value();
  1825. !         errormsg = NO;
  1826.           message(NullStr);
  1827.       } else
  1828.           ExecCmd(cp);
  1829. ***************
  1830. *** 662,668 ****
  1831.   
  1832.   dorecover()
  1833.   {
  1834. !     execl(Recover, "jove_recover", "-d", TmpFilePath, (char *)0);
  1835.       printf("%s: execl failed!\n", Recover);
  1836.       flusho();
  1837.       _exit(-1);
  1838. --- 659,665 ----
  1839.   
  1840.   dorecover()
  1841.   {
  1842. !     execl(Recover, "jove_recover", "-d", TmpFilePath, (char *) 0);
  1843.       printf("%s: execl failed!\n", Recover);
  1844.       flusho();
  1845.       _exit(-1);
  1846. ***************
  1847. *** 721,727 ****
  1848.               case 't':
  1849.                   ++argv;
  1850.                   --argc;
  1851. -                 exp_p = YES;
  1852.                   find_tag(argv[1], YES);
  1853.                   break;
  1854.   
  1855. --- 718,723 ----
  1856. ***************
  1857. *** 812,818 ****
  1858.       Mark    *m;
  1859.   
  1860.       sprintf(bname, "%s", curbuf->b_name);
  1861. !     m = MakeMark(curline, curchar, FLOATER);
  1862.   
  1863.       RecDepth++;
  1864.       UpdModLine++;
  1865. --- 808,814 ----
  1866.       Mark    *m;
  1867.   
  1868.       sprintf(bname, "%s", curbuf->b_name);
  1869. !     m = MakeMark(curline, curchar, M_FLOATER);
  1870.   
  1871.       RecDepth++;
  1872.       UpdModLine++;
  1873. ***************
  1874. *** 820,826 ****
  1875.       UpdModLine++;
  1876.       RecDepth--;
  1877.       SetBuf(do_select(curwind, bname));
  1878. !     if (exp_p == NO)
  1879.           ToMark(m);
  1880.       DelMark(m);
  1881.   }
  1882. --- 816,822 ----
  1883.       UpdModLine++;
  1884.       RecDepth--;
  1885.       SetBuf(do_select(curwind, bname));
  1886. !     if (!is_an_arg())
  1887.           ToMark(m);
  1888.       DelMark(m);
  1889.   }
  1890. ***************
  1891. *** 846,858 ****
  1892.           if (RecDepth == 0) {
  1893.               if (ModMacs()) {
  1894.                   rbell();
  1895. !                 if (Upper(*ask("No",
  1896.   "Some MACROS haven't been saved; leave anyway? ")) != 'Y')
  1897.                       break;
  1898.               }
  1899.               if (ModBufs(0)) {
  1900.                   rbell();
  1901. !                 if (Upper(*ask("No",
  1902.   "Some buffers haven't been saved; leave anyway? ")) != 'Y')
  1903.                       break;
  1904.               }
  1905. --- 842,854 ----
  1906.           if (RecDepth == 0) {
  1907.               if (ModMacs()) {
  1908.                   rbell();
  1909. !                 if (CharUpcase(*ask("No",
  1910.   "Some MACROS haven't been saved; leave anyway? ")) != 'Y')
  1911.                       break;
  1912.               }
  1913.               if (ModBufs(0)) {
  1914.                   rbell();
  1915. !                 if (CharUpcase(*ask("No",
  1916.   "Some buffers haven't been saved; leave anyway? ")) != 'Y')
  1917.                       break;
  1918.               }
  1919. ***************
  1920. *** 880,887 ****
  1921.   
  1922.       for (;;) {
  1923.           if (this_cmd != ARG_CMD) {
  1924. !             exp = 1;
  1925. !             exp_p = NO;
  1926.               last_cmd = this_cmd;
  1927.               init_strokes();
  1928.           }
  1929. --- 876,882 ----
  1930.   
  1931.       for (;;) {
  1932.           if (this_cmd != ARG_CMD) {
  1933. !             clr_arg_value();
  1934.               last_cmd = this_cmd;
  1935.               init_strokes();
  1936.           }
  1937. ***************
  1938. *** 1051,1061 ****
  1939.       }
  1940.       if (scanvec(argv, "-r"))
  1941.           dorecover();
  1942.   
  1943. -     (void) time(&time0);
  1944.       ttinit();    /* initialize terminal (after ~/.joverc) */
  1945.       settout(ttbuf);    /* not until we know baudrate */
  1946. -     ResetTerm();
  1947.   
  1948.       (void) signal(SIGHUP, finish);
  1949.       (void) signal(SIGINT, finish);
  1950. --- 1046,1056 ----
  1951.       }
  1952.       if (scanvec(argv, "-r"))
  1953.           dorecover();
  1954. +     if (scanvec(argv, "-rc"))
  1955. +         FullRecover();
  1956.   
  1957.       ttinit();    /* initialize terminal (after ~/.joverc) */
  1958.       settout(ttbuf);    /* not until we know baudrate */
  1959.   
  1960.       (void) signal(SIGHUP, finish);
  1961.       (void) signal(SIGINT, finish);
  1962. ***************
  1963. *** 1071,1078 ****
  1964.   
  1965.       /* set things up to update the modeline every UpdFreq seconds */
  1966.       (void) signal(SIGALRM, updmode);
  1967. !     (void) alarm((unsigned) UpdFreq);
  1968.   
  1969.       cl_scr(1);
  1970.       flusho();
  1971.       RedrawDisplay();    /* start the redisplay process. */
  1972. --- 1066,1075 ----
  1973.   
  1974.       /* set things up to update the modeline every UpdFreq seconds */
  1975.       (void) signal(SIGALRM, updmode);
  1976. !     (void) time(&time0);
  1977. !     (void) alarm((unsigned) (60 - (time0 % 60)));
  1978.   
  1979. +     ResetTerm();
  1980.       cl_scr(1);
  1981.       flusho();
  1982.       RedrawDisplay();    /* start the redisplay process. */
  1983.