1: /* Copyright (c) 1981 Regents of the University of California */
   2: static char *sccsid = "@(#)ex_subr.c	7.2	7/26/81";
   3: #include "ex.h"
   4: #include "ex_re.h"
   5: #include "ex_tty.h"
   6: #include "ex_vis.h"
   7: 
   8: /*
   9:  * Random routines, in alphabetical order.
  10:  */
  11: 
  12: any(c, s)
  13:     int c;
  14:     register char *s;
  15: {
  16:     register int x;
  17: 
  18:     while (x = *s++)
  19:         if (x == c)
  20:             return (1);
  21:     return (0);
  22: }
  23: 
  24: backtab(i)
  25:     register int i;
  26: {
  27:     register int j;
  28: 
  29:     j = i % value(SHIFTWIDTH);
  30:     if (j == 0)
  31:         j = value(SHIFTWIDTH);
  32:     i -= j;
  33:     if (i < 0)
  34:         i = 0;
  35:     return (i);
  36: }
  37: 
  38: change()
  39: {
  40: 
  41:     tchng++;
  42:     chng = tchng;
  43: }
  44: 
  45: /*
  46:  * Column returns the number of
  47:  * columns occupied by printing the
  48:  * characters through position cp of the
  49:  * current line.
  50:  */
  51: column(cp)
  52:     register char *cp;
  53: {
  54: 
  55:     if (cp == 0)
  56:         cp = &linebuf[LBSIZE - 2];
  57:     return (qcolumn(cp, (char *) 0));
  58: }
  59: 
  60: /*
  61:  * Ignore a comment to the end of the line.
  62:  * This routine eats the trailing newline so don't call newline().
  63:  */
  64: comment()
  65: {
  66:     register int c;
  67: 
  68:     do {
  69:         c = getchar();
  70:     } while (c != '\n' && c != EOF);
  71:     if (c == EOF)
  72:         ungetchar(c);
  73: }
  74: 
  75: Copy(to, from, size)
  76:     register char *from, *to;
  77:     register int size;
  78: {
  79: 
  80:     if (size > 0)
  81:         do
  82:             *to++ = *from++;
  83:         while (--size > 0);
  84: }
  85: 
  86: copyw(to, from, size)
  87:     register line *from, *to;
  88:     register int size;
  89: {
  90: 
  91:     if (size > 0)
  92:         do
  93:             *to++ = *from++;
  94:         while (--size > 0);
  95: }
  96: 
  97: copywR(to, from, size)
  98:     register line *from, *to;
  99:     register int size;
 100: {
 101: 
 102:     while (--size >= 0)
 103:         to[size] = from[size];
 104: }
 105: 
 106: ctlof(c)
 107:     int c;
 108: {
 109: 
 110:     return (c == TRIM ? '?' : c | ('A' - 1));
 111: }
 112: 
 113: dingdong()
 114: {
 115: 
 116:     if (VB)
 117:         putpad(VB);
 118:     else if (value(ERRORBELLS))
 119:         putch('\207');
 120: }
 121: 
 122: fixindent(indent)
 123:     int indent;
 124: {
 125:     register int i;
 126:     register char *cp;
 127: 
 128:     i = whitecnt(genbuf);
 129:     cp = vpastwh(genbuf);
 130:     if (*cp == 0 && i == indent && linebuf[0] == 0) {
 131:         genbuf[0] = 0;
 132:         return (i);
 133:     }
 134:     CP(genindent(i), cp);
 135:     return (i);
 136: }
 137: 
 138: filioerr(cp)
 139:     char *cp;
 140: {
 141:     register int oerrno = errno;
 142: 
 143:     lprintf("\"%s\"", cp);
 144:     errno = oerrno;
 145:     syserror();
 146: }
 147: 
 148: char *
 149: genindent(indent)
 150:     register int indent;
 151: {
 152:     register char *cp;
 153: 
 154:     for (cp = genbuf; indent >= value(TABSTOP); indent -= value(TABSTOP))
 155:         *cp++ = '\t';
 156:     for (; indent > 0; indent--)
 157:         *cp++ = ' ';
 158:     return (cp);
 159: }
 160: 
 161: getDOT()
 162: {
 163: 
 164:     getline(*dot);
 165: }
 166: 
 167: line *
 168: getmark(c)
 169:     register int c;
 170: {
 171:     register line *addr;
 172: 
 173:     for (addr = one; addr <= dol; addr++)
 174:         if (names[c - 'a'] == (*addr &~ 01)) {
 175:             return (addr);
 176:         }
 177:     return (0);
 178: }
 179: 
 180: getn(cp)
 181:     register char *cp;
 182: {
 183:     register int i = 0;
 184: 
 185:     while (isdigit(*cp))
 186:         i = i * 10 + *cp++ - '0';
 187:     if (*cp)
 188:         return (0);
 189:     return (i);
 190: }
 191: 
 192: ignnEOF()
 193: {
 194:     register int c = getchar();
 195: 
 196:     if (c == EOF)
 197:         ungetchar(c);
 198:     else if (c=='"')
 199:         comment();
 200: }
 201: 
 202: iswhite(c)
 203:     int c;
 204: {
 205: 
 206:     return (c == ' ' || c == '\t');
 207: }
 208: 
 209: junk(c)
 210:     register int c;
 211: {
 212: 
 213:     if (c && !value(BEAUTIFY))
 214:         return (0);
 215:     if (c >= ' ' && c != TRIM)
 216:         return (0);
 217:     switch (c) {
 218: 
 219:     case '\t':
 220:     case '\n':
 221:     case '\f':
 222:         return (0);
 223: 
 224:     default:
 225:         return (1);
 226:     }
 227: }
 228: 
 229: killed()
 230: {
 231: 
 232:     killcnt(addr2 - addr1 + 1);
 233: }
 234: 
 235: killcnt(cnt)
 236:     register int cnt;
 237: {
 238: 
 239:     if (inopen) {
 240:         notecnt = cnt;
 241:         notenam = notesgn = "";
 242:         return;
 243:     }
 244:     if (!notable(cnt))
 245:         return;
 246:     printf("%d lines", cnt);
 247:     if (value(TERSE) == 0) {
 248:         printf(" %c%s", Command[0] | ' ', Command + 1);
 249:         if (Command[strlen(Command) - 1] != 'e')
 250:             putchar('e');
 251:         putchar('d');
 252:     }
 253:     putNFL();
 254: }
 255: 
 256: lineno(a)
 257:     line *a;
 258: {
 259: 
 260:     return (a - zero);
 261: }
 262: 
 263: lineDOL()
 264: {
 265: 
 266:     return (lineno(dol));
 267: }
 268: 
 269: lineDOT()
 270: {
 271: 
 272:     return (lineno(dot));
 273: }
 274: 
 275: markDOT()
 276: {
 277: 
 278:     markpr(dot);
 279: }
 280: 
 281: markpr(which)
 282:     line *which;
 283: {
 284: 
 285:     if ((inglobal == 0 || inopen) && which <= endcore) {
 286:         names['z'-'a'+1] = *which & ~01;
 287:         if (inopen)
 288:             ncols['z'-'a'+1] = cursor;
 289:     }
 290: }
 291: 
 292: markreg(c)
 293:     register int c;
 294: {
 295: 
 296:     if (c == '\'' || c == '`')
 297:         return ('z' + 1);
 298:     if (c >= 'a' && c <= 'z')
 299:         return (c);
 300:     return (0);
 301: }
 302: 
 303: /*
 304:  * Mesg decodes the terse/verbose strings. Thus
 305:  *	'xxx@yyy' -> 'xxx' if terse, else 'xxx yyy'
 306:  *	'xxx|yyy' -> 'xxx' if terse, else 'yyy'
 307:  * All others map to themselves.
 308:  */
 309: char *
 310: mesg(str)
 311:     register char *str;
 312: {
 313:     register char *cp;
 314: 
 315:     str = strcpy(genbuf, str);
 316:     for (cp = str; *cp; cp++)
 317:         switch (*cp) {
 318: 
 319:         case '@':
 320:             if (value(TERSE))
 321:                 *cp = 0;
 322:             else
 323:                 *cp = ' ';
 324:             break;
 325: 
 326:         case '|':
 327:             if (value(TERSE) == 0)
 328:                 return (cp + 1);
 329:             *cp = 0;
 330:             break;
 331:         }
 332:     return (str);
 333: }
 334: 
 335: /*VARARGS2*/
 336: merror(seekpt, i)
 337: #ifdef VMUNIX
 338:     char *seekpt;
 339: #else
 340: # ifdef lint
 341:     char *seekpt;
 342: # else
 343:     int seekpt;
 344: # endif
 345: #endif
 346:     int i;
 347: {
 348:     register char *cp = linebuf;
 349: 
 350:     if (seekpt == 0)
 351:         return;
 352:     merror1(seekpt);
 353:     if (*cp == '\n')
 354:         putnl(), cp++;
 355:     if (inopen > 0 && CE)
 356:         vclreol();
 357:     if (SO && SE)
 358:         putpad(SO);
 359:     printf(mesg(cp), i);
 360:     if (SO && SE)
 361:         putpad(SE);
 362: }
 363: 
 364: merror1(seekpt)
 365: #ifdef VMUNIX
 366:     char *seekpt;
 367: #else
 368: # ifdef lint
 369:     char *seekpt;
 370: # else
 371:     int seekpt;
 372: # endif
 373: #endif
 374: {
 375: 
 376: #ifdef VMUNIX
 377:     strcpy(linebuf, seekpt);
 378: #else
 379:     lseek(erfile, (long) seekpt, 0);
 380:     if (read(erfile, linebuf, 128) < 2)
 381:         CP(linebuf, "ERROR");
 382: #endif
 383: }
 384: 
 385: morelines()
 386: {
 387: #ifdef  pdp11
 388: #define MAXDATA (56*1024)
 389:     register char *end;
 390: 
 391:     if ((int) sbrk(1024 * sizeof (line)) != -1) {
 392:         endcore += 1024;
 393:     } else {
 394:         if (endcore >= MAXDATA)
 395:             return(-1);
 396:         end = MAXDATA;
 397:         /*
 398: 		 * Ask for end+2 since we want end to be last used location.
 399: 		 */
 400:         while (brk(end+2) == -1)
 401:             end -= 64;
 402:         if (end <= (char *)endcore)
 403:             return(-1);
 404:         endcore = (line *) end;
 405:     }
 406:     return(0);
 407: #else
 408:     if ((int) sbrk(1024 * sizeof (line)) == -1)
 409:         return (-1);
 410:     endcore += 1024;
 411:     return (0);
 412: #endif
 413: }
 414: 
 415: nonzero()
 416: {
 417: 
 418:     if (addr1 == zero) {
 419:         notempty();
 420:         error("Nonzero address required@on this command");
 421:     }
 422: }
 423: 
 424: notable(i)
 425:     int i;
 426: {
 427: 
 428:     return (hush == 0 && !inglobal && i > value(REPORT));
 429: }
 430: 
 431: 
 432: notempty()
 433: {
 434: 
 435:     if (dol == zero)
 436:         error("No lines@in the buffer");
 437: }
 438: 
 439: 
 440: netchHAD(cnt)
 441:     int cnt;
 442: {
 443: 
 444:     netchange(lineDOL() - cnt);
 445: }
 446: 
 447: netchange(i)
 448:     register int i;
 449: {
 450:     register char *cp;
 451: 
 452:     if (i > 0)
 453:         notesgn = cp = "more ";
 454:     else
 455:         notesgn = cp = "fewer ", i = -i;
 456:     if (inopen) {
 457:         notecnt = i;
 458:         notenam = "";
 459:         return;
 460:     }
 461:     if (!notable(i))
 462:         return;
 463:     printf(mesg("%d %slines@in file after %s"), i, cp, Command);
 464:     putNFL();
 465: }
 466: 
 467: putmark(addr)
 468:     line *addr;
 469: {
 470: 
 471:     putmk1(addr, putline());
 472: }
 473: 
 474: putmk1(addr, n)
 475:     register line *addr;
 476:     int n;
 477: {
 478:     register line *markp;
 479:     register oldglobmk;
 480: 
 481:     oldglobmk = *addr & 1;
 482:     *addr &= ~1;
 483:     for (markp = (anymarks ? names : &names['z'-'a'+1]);
 484:       markp <= &names['z'-'a'+1]; markp++)
 485:         if (*markp == *addr)
 486:             *markp = n;
 487:     *addr = n | oldglobmk;
 488: }
 489: 
 490: char *
 491: plural(i)
 492:     long i;
 493: {
 494: 
 495:     return (i == 1 ? "" : "s");
 496: }
 497: 
 498: int qcount();
 499: short   vcntcol;
 500: 
 501: qcolumn(lim, gp)
 502:     register char *lim, *gp;
 503: {
 504:     register int x;
 505:     int (*OO)();
 506: 
 507:     OO = Outchar;
 508:     Outchar = qcount;
 509:     vcntcol = 0;
 510:     if (lim != NULL)
 511:         x = lim[1], lim[1] = 0;
 512:     pline(0);
 513:     if (lim != NULL)
 514:         lim[1] = x;
 515:     if (gp)
 516:         while (*gp)
 517:             putchar(*gp++);
 518:     Outchar = OO;
 519:     return (vcntcol);
 520: }
 521: 
 522: int
 523: qcount(c)
 524:     int c;
 525: {
 526: 
 527:     if (c == '\t') {
 528:         vcntcol += value(TABSTOP) - vcntcol % value(TABSTOP);
 529:         return;
 530:     }
 531:     vcntcol++;
 532: }
 533: 
 534: reverse(a1, a2)
 535:     register line *a1, *a2;
 536: {
 537:     register line t;
 538: 
 539:     for (;;) {
 540:         t = *--a2;
 541:         if (a2 <= a1)
 542:             return;
 543:         *a2 = *a1;
 544:         *a1++ = t;
 545:     }
 546: }
 547: 
 548: save(a1, a2)
 549:     line *a1;
 550:     register line *a2;
 551: {
 552:     register int more;
 553: 
 554:     if (!FIXUNDO)
 555:         return;
 556: #ifdef TRACE
 557:     if (trace)
 558:         vudump("before save");
 559: #endif
 560:     undkind = UNDNONE;
 561:     undadot = dot;
 562:     more = (a2 - a1 + 1) - (unddol - dol);
 563:     while (more > (endcore - truedol))
 564:         if (morelines() < 0)
 565:             error("Out of memory@saving lines for undo - try using ed");
 566:     if (more)
 567:         (*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1,
 568:             (truedol - unddol));
 569:     unddol += more;
 570:     truedol += more;
 571:     copyw(dol + 1, a1, a2 - a1 + 1);
 572:     undkind = UNDALL;
 573:     unddel = a1 - 1;
 574:     undap1 = a1;
 575:     undap2 = a2 + 1;
 576: #ifdef TRACE
 577:     if (trace)
 578:         vudump("after save");
 579: #endif
 580: }
 581: 
 582: save12()
 583: {
 584: 
 585:     save(addr1, addr2);
 586: }
 587: 
 588: saveall()
 589: {
 590: 
 591:     save(one, dol);
 592: }
 593: 
 594: span()
 595: {
 596: 
 597:     return (addr2 - addr1 + 1);
 598: }
 599: 
 600: sync()
 601: {
 602: 
 603:     chng = 0;
 604:     tchng = 0;
 605:     xchng = 0;
 606: }
 607: 
 608: 
 609: skipwh()
 610: {
 611:     register int wh;
 612: 
 613:     wh = 0;
 614:     while (iswhite(peekchar())) {
 615:         wh++;
 616:         ignchar();
 617:     }
 618:     return (wh);
 619: }
 620: 
 621: /*VARARGS2*/
 622: smerror(seekpt, cp)
 623: #ifdef lint
 624:     char *seekpt;
 625: #else
 626:     int seekpt;
 627: #endif
 628:     char *cp;
 629: {
 630: 
 631:     if (seekpt == 0)
 632:         return;
 633:     merror1(seekpt);
 634:     if (inopen && CE)
 635:         vclreol();
 636:     if (SO && SE)
 637:         putpad(SO);
 638:     lprintf(mesg(linebuf), cp);
 639:     if (SO && SE)
 640:         putpad(SE);
 641: }
 642: 
 643: #define std_nerrs (sizeof std_errlist / sizeof std_errlist[0])
 644: 
 645: #define error(i)    i
 646: 
 647: #ifdef lint
 648: char    *std_errlist[] = {
 649: #else
 650: # ifdef VMUNIX
 651: char    *std_errlist[] = {
 652: # else
 653: short   std_errlist[] = {
 654: # endif
 655: #endif
 656:     error("Error 0"),
 657:     error("Not super-user"),
 658:     error("No such file or directory"),
 659:     error("No such process"),
 660:     error("Interrupted system call"),
 661:     error("Physical I/O error"),
 662:     error("No such device or address"),
 663:     error("Argument list too long"),
 664:     error("Exec format error"),
 665:     error("Bad file number"),
 666:     error("No children"),
 667:     error("No more processes"),
 668:     error("Not enough core"),
 669:     error("Permission denied"),
 670:     error("Bad address"),
 671:     error("Block device required"),
 672:     error("Mount device busy"),
 673:     error("File exists"),
 674:     error("Cross-device link"),
 675:     error("No such device"),
 676:     error("Not a directory"),
 677:     error("Is a directory"),
 678:     error("Invalid argument"),
 679:     error("File table overflow"),
 680:     error("Too many open files"),
 681:     error("Not a typewriter"),
 682:     error("Text file busy"),
 683:     error("File too large"),
 684:     error("No space left on device"),
 685:     error("Illegal seek"),
 686:     error("Read-only file system"),
 687:     error("Too many links"),
 688:     error("Broken pipe"),
 689: #ifndef V6
 690:     error("Math argument"),
 691:     error("Result too large"),
 692: #endif
 693:     error("Quota exceeded")     /* Berkeley quota systems only */
 694: };
 695: 
 696: #undef  error
 697: 
 698: char *
 699: strend(cp)
 700:     register char *cp;
 701: {
 702: 
 703:     while (*cp)
 704:         cp++;
 705:     return (cp);
 706: }
 707: 
 708: strcLIN(dp)
 709:     char *dp;
 710: {
 711: 
 712:     CP(linebuf, dp);
 713: }
 714: 
 715: syserror()
 716: {
 717:     register int e = errno;
 718: 
 719:     dirtcnt = 0;
 720:     putchar(' ');
 721:     edited = 0; /* for temp file errors, for example */
 722:     if (e >= 0 && errno <= std_nerrs)
 723:         error(std_errlist[e]);
 724:     else
 725:         error("System error %d", e);
 726: }
 727: 
 728: /*
 729:  * Return the column number that results from being in column col and
 730:  * hitting a tab, where tabs are set every ts columns.  Work right for
 731:  * the case where col > COLUMNS, even if ts does not divide COLUMNS.
 732:  */
 733: tabcol(col, ts)
 734: int col, ts;
 735: {
 736:     int offset, result;
 737: 
 738:     if (col >= COLUMNS) {
 739:         offset = COLUMNS * (col/COLUMNS);
 740:         col -= offset;
 741:     } else
 742:         offset = 0;
 743:     result = col + ts - (col % ts) + offset;
 744:     return (result);
 745: }
 746: 
 747: char *
 748: vfindcol(i)
 749:     int i;
 750: {
 751:     register char *cp;
 752:     register int (*OO)() = Outchar;
 753: 
 754:     Outchar = qcount;
 755:     ignore(qcolumn(linebuf - 1, NOSTR));
 756:     for (cp = linebuf; *cp && vcntcol < i; cp++)
 757:         putchar(*cp);
 758:     if (cp != linebuf)
 759:         cp--;
 760:     Outchar = OO;
 761:     return (cp);
 762: }
 763: 
 764: char *
 765: vskipwh(cp)
 766:     register char *cp;
 767: {
 768: 
 769:     while (iswhite(*cp) && cp[1])
 770:         cp++;
 771:     return (cp);
 772: }
 773: 
 774: 
 775: char *
 776: vpastwh(cp)
 777:     register char *cp;
 778: {
 779: 
 780:     while (iswhite(*cp))
 781:         cp++;
 782:     return (cp);
 783: }
 784: 
 785: whitecnt(cp)
 786:     register char *cp;
 787: {
 788:     register int i;
 789: 
 790:     i = 0;
 791:     for (;;)
 792:         switch (*cp++) {
 793: 
 794:         case '\t':
 795:             i += value(TABSTOP) - i % value(TABSTOP);
 796:             break;
 797: 
 798:         case ' ':
 799:             i++;
 800:             break;
 801: 
 802:         default:
 803:             return (i);
 804:         }
 805: }
 806: 
 807: #ifdef lint
 808: Ignore(a)
 809:     char *a;
 810: {
 811: 
 812:     a = a;
 813: }
 814: 
 815: Ignorf(a)
 816:     int (*a)();
 817: {
 818: 
 819:     a = a;
 820: }
 821: #endif
 822: 
 823: markit(addr)
 824:     line *addr;
 825: {
 826: 
 827:     if (addr != dot && addr >= one && addr <= dol)
 828:         markDOT();
 829: }
 830: 
 831: /*
 832:  * The following code is defensive programming against a bug in the
 833:  * pdp-11 overlay implementation.  Sometimes it goes nuts and asks
 834:  * for an overlay with some garbage number, which generates an emt
 835:  * trap.  This is a less than elegant solution, but it is somewhat
 836:  * better than core dumping and losing your work, leaving your tty
 837:  * in a weird state, etc.
 838:  */
 839: int _ovno;
 840: onemt()
 841: {
 842:     int oovno;
 843: 
 844:     signal(SIGEMT, onemt);
 845:     oovno = _ovno;
 846:     /* 2 and 3 are valid on 11/40 type vi, so */
 847:     if (_ovno < 0 || _ovno > 3)
 848:         _ovno = 0;
 849:     error("emt trap, _ovno is %d @ - try again");
 850: }
 851: 
 852: /*
 853:  * When a hangup occurs our actions are similar to a preserve
 854:  * command.  If the buffer has not been [Modified], then we do
 855:  * nothing but remove the temporary files and exit.
 856:  * Otherwise, we sync the temp file and then attempt a preserve.
 857:  * If the preserve succeeds, we unlink our temp files.
 858:  * If the preserve fails, we leave the temp files as they are
 859:  * as they are a backup even without preservation if they
 860:  * are not removed.
 861:  */
 862: onhup()
 863: {
 864: 
 865:     /*
 866: 	 * USG tty driver can send multiple HUP's!!
 867: 	 */
 868:     signal(SIGINT, SIG_IGN);
 869:     signal(SIGHUP, SIG_IGN);
 870:     if (chng == 0) {
 871:         cleanup(1);
 872:         exit(0);
 873:     }
 874:     if (setexit() == 0) {
 875:         if (preserve()) {
 876:             cleanup(1);
 877:             exit(0);
 878:         }
 879:     }
 880:     exit(1);
 881: }
 882: 
 883: /*
 884:  * An interrupt occurred.  Drain any output which
 885:  * is still in the output buffering pipeline.
 886:  * Catch interrupts again.  Unless we are in visual
 887:  * reset the output state (out of -nl mode, e.g).
 888:  * Then like a normal error (with the \n before Interrupt
 889:  * suppressed in visual mode).
 890:  */
 891: onintr()
 892: {
 893: 
 894: #ifndef CBREAK
 895:     signal(SIGINT, onintr);
 896: #else
 897:     signal(SIGINT, inopen ? vintr : onintr);
 898: #endif
 899:     alarm(0);   /* in case we were called from map */
 900:     draino();
 901:     if (!inopen) {
 902:         pstop();
 903:         setlastchar('\n');
 904: #ifdef CBREAK
 905:     }
 906: #else
 907:     } else
 908:         vraw();
 909: #endif
 910:     error("\nInterrupt" + inopen);
 911: }
 912: 
 913: /*
 914:  * If we are interruptible, enable interrupts again.
 915:  * In some critical sections we turn interrupts off,
 916:  * but not very often.
 917:  */
 918: setrupt()
 919: {
 920: 
 921:     if (ruptible) {
 922: #ifndef CBREAK
 923:         signal(SIGINT, onintr);
 924: #else
 925:         signal(SIGINT, inopen ? vintr : onintr);
 926: #endif
 927: #ifdef SIGTSTP
 928:         if (dosusp)
 929:             signal(SIGTSTP, onsusp);
 930: #endif
 931:     }
 932: }
 933: 
 934: preserve()
 935: {
 936: 
 937: #ifdef VMUNIX
 938:     tflush();
 939: #endif
 940:     synctmp();
 941:     pid = fork();
 942:     if (pid < 0)
 943:         return (0);
 944:     if (pid == 0) {
 945:         close(0);
 946:         dup(tfile);
 947:         execl(EXPRESERVE, "expreserve", (char *) 0);
 948:         exit(1);
 949:     }
 950:     waitfor();
 951:     if (rpid == pid && status == 0)
 952:         return (1);
 953:     return (0);
 954: }
 955: 
 956: #ifndef V6
 957: exit(i)
 958:     int i;
 959: {
 960: 
 961: # ifdef TRACE
 962:     if (trace)
 963:         fclose(trace);
 964: # endif
 965:     _exit(i);
 966: }
 967: #endif
 968: 
 969: #ifdef SIGTSTP
 970: /*
 971:  * We have just gotten a susp.  Suspend and prepare to resume.
 972:  */
 973: onsusp()
 974: {
 975:     ttymode f;
 976: 
 977:     f = setty(normf);
 978:     vnfl();
 979:     putpad(TE);
 980:     flush();
 981: 
 982:     signal(SIGTSTP, SIG_DFL);
 983:     kill(0, SIGTSTP);
 984: 
 985:     /* the pc stops here */
 986: 
 987:     signal(SIGTSTP, onsusp);
 988:     vcontin(0);
 989:     setty(f);
 990:     if (!inopen)
 991:         error(0);
 992:     else {
 993:         if (vcnt < 0) {
 994:             vcnt = -vcnt;
 995:             if (state == VISUAL)
 996:                 vclear();
 997:             else if (state == CRTOPEN)
 998:                 vcnt = 0;
 999:         }
1000:         vdirty(0, LINES);
1001:         vrepaint(cursor);
1002:     }
1003: }

Defined functions

Copy defined in line 75; used 1 times
backtab defined in line 24; used 3 times
comment defined in line 64; used 3 times
copyw defined in line 86; used 6 times
copywR defined in line 97; used 3 times
ctlof defined in line 106; used 5 times
dingdong defined in line 113; used 2 times
fixindent defined in line 122; used 1 times
getn defined in line 180; never used
ignnEOF defined in line 192; used 1 times
iswhite defined in line 202; used 8 times
junk defined in line 209; used 2 times
killcnt defined in line 235; used 3 times
killed defined in line 229; used 5 times
markpr defined in line 281; used 5 times
merror defined in line 336; used 4 times
merror1 defined in line 364; used 2 times
morelines defined in line 385; used 3 times
netchange defined in line 447; used 2 times
notable defined in line 424; used 3 times
onsusp defined in line 973; used 4 times
preserve defined in line 934; used 2 times
putmk1 defined in line 474; used 2 times
qcolumn defined in line 501; used 5 times
qcount defined in line 522; used 4 times
reverse defined in line 534; used 15 times
save defined in line 548; used 2 times
save12 defined in line 582; used 3 times
smerror defined in line 622; used 2 times
span defined in line 594; used 1 times

Defined variables

sccsid defined in line 2; never used
std_errlist defined in line 651; used 4 times
vcntcol defined in line 499; used 6 times

Defined macros

MAXDATA defined in line 388; used 2 times
error defined in line 645; used 45 times
std_nerrs defined in line 643; used 1 times
Last modified: 1982-07-29
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2502
Valid CSS Valid XHTML 1.0 Strict