|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: #include "ex.h" ! 3: #include "ex_re.h" ! 4: #include "ex_tty.h" ! 5: #include "ex_vis.h" ! 6: ! 7: /* ! 8: * Random routines, in alphabetical order. ! 9: */ ! 10: ! 11: any(c, s) ! 12: int c; ! 13: register char *s; ! 14: { ! 15: register int x; ! 16: ! 17: while (x = *s++) ! 18: if (x == c) ! 19: return (1); ! 20: return (0); ! 21: } ! 22: ! 23: backtab(i) ! 24: register int i; ! 25: { ! 26: register int j; ! 27: ! 28: j = i % value(SHIFTWIDTH); ! 29: if (j == 0) ! 30: j = value(SHIFTWIDTH); ! 31: i -= j; ! 32: if (i < 0) ! 33: i = 0; ! 34: return (i); ! 35: } ! 36: ! 37: change() ! 38: { ! 39: ! 40: tchng++; ! 41: chng = tchng; ! 42: } ! 43: ! 44: /* ! 45: * Column returns the number of ! 46: * columns occupied by printing the ! 47: * characters through position cp of the ! 48: * current line. ! 49: */ ! 50: column(cp) ! 51: register char *cp; ! 52: { ! 53: ! 54: if (cp == 0) ! 55: cp = &linebuf[LBSIZE - 2]; ! 56: return (qcolumn(cp, (char *) 0)); ! 57: } ! 58: ! 59: Copy(to, from, size) ! 60: register char *from, *to; ! 61: register int size; ! 62: { ! 63: ! 64: if (size > 0) ! 65: do ! 66: *to++ = *from++; ! 67: while (--size > 0); ! 68: } ! 69: ! 70: copyw(to, from, size) ! 71: register line *from, *to; ! 72: register int size; ! 73: { ! 74: ! 75: if (size > 0) ! 76: do ! 77: *to++ = *from++; ! 78: while (--size > 0); ! 79: } ! 80: ! 81: copywR(to, from, size) ! 82: register line *from, *to; ! 83: register int size; ! 84: { ! 85: ! 86: while (--size >= 0) ! 87: to[size] = from[size]; ! 88: } ! 89: ! 90: ctlof(c) ! 91: int c; ! 92: { ! 93: ! 94: return (c == TRIM ? '?' : c | ('A' - 1)); ! 95: } ! 96: ! 97: dingdong() ! 98: { ! 99: ! 100: if (VB) ! 101: putpad(VB); ! 102: else if (value(ERRORBELLS)) ! 103: putch('\207'); ! 104: } ! 105: ! 106: fixindent(indent) ! 107: int indent; ! 108: { ! 109: register int i; ! 110: register char *cp; ! 111: ! 112: i = whitecnt(genbuf); ! 113: cp = vpastwh(genbuf); ! 114: if (*cp == 0 && i == indent && linebuf[0] == 0) { ! 115: genbuf[0] = 0; ! 116: return (i); ! 117: } ! 118: CP(genindent(i), cp); ! 119: return (i); ! 120: } ! 121: ! 122: filioerr(cp) ! 123: char *cp; ! 124: { ! 125: register int oerrno = errno; ! 126: ! 127: lprintf("\"%s\"", cp); ! 128: errno = oerrno; ! 129: syserror(); ! 130: } ! 131: ! 132: char * ! 133: genindent(indent) ! 134: register int indent; ! 135: { ! 136: register char *cp; ! 137: ! 138: for (cp = genbuf; indent >= value(TABSTOP); indent -= value(TABSTOP)) ! 139: *cp++ = '\t'; ! 140: for (; indent > 0; indent--) ! 141: *cp++ = ' '; ! 142: return (cp); ! 143: } ! 144: ! 145: getDOT() ! 146: { ! 147: ! 148: getline(*dot); ! 149: } ! 150: ! 151: line * ! 152: getmark(c) ! 153: register int c; ! 154: { ! 155: register line *addr; ! 156: ! 157: for (addr = one; addr <= dol; addr++) ! 158: if (names[c - 'a'] == (*addr &~ 01)) { ! 159: return (addr); ! 160: } ! 161: return (0); ! 162: } ! 163: ! 164: getn(cp) ! 165: register char *cp; ! 166: { ! 167: register int i = 0; ! 168: ! 169: while (isdigit(*cp)) ! 170: i = i * 10 + *cp++ - '0'; ! 171: if (*cp) ! 172: return (0); ! 173: return (i); ! 174: } ! 175: ! 176: ignnEOF() ! 177: { ! 178: register int c = getchar(); ! 179: ! 180: if (c == EOF) ! 181: ungetchar(c); ! 182: } ! 183: ! 184: iswhite(c) ! 185: int c; ! 186: { ! 187: ! 188: return (c == ' ' || c == '\t'); ! 189: } ! 190: ! 191: junk(c) ! 192: register int c; ! 193: { ! 194: ! 195: if (c && !value(BEAUTIFY)) ! 196: return (0); ! 197: if (c >= ' ' && c != TRIM) ! 198: return (0); ! 199: switch (c) { ! 200: ! 201: case '\t': ! 202: case '\n': ! 203: case '\f': ! 204: return (0); ! 205: ! 206: default: ! 207: return (1); ! 208: } ! 209: } ! 210: ! 211: killed() ! 212: { ! 213: ! 214: killcnt(addr2 - addr1 + 1); ! 215: } ! 216: ! 217: killcnt(cnt) ! 218: register int cnt; ! 219: { ! 220: ! 221: if (inopen) { ! 222: notecnt = cnt; ! 223: notenam = notesgn = ""; ! 224: return; ! 225: } ! 226: if (!notable(cnt)) ! 227: return; ! 228: printf("%d lines", cnt); ! 229: if (value(TERSE) == 0) { ! 230: printf(" %c%s", Command[0] | ' ', Command + 1); ! 231: if (Command[strlen(Command) - 1] != 'e') ! 232: putchar('e'); ! 233: putchar('d'); ! 234: } ! 235: putNFL(); ! 236: } ! 237: ! 238: lineno(a) ! 239: line *a; ! 240: { ! 241: ! 242: return (a - zero); ! 243: } ! 244: ! 245: lineDOL() ! 246: { ! 247: ! 248: return (lineno(dol)); ! 249: } ! 250: ! 251: lineDOT() ! 252: { ! 253: ! 254: return (lineno(dot)); ! 255: } ! 256: ! 257: markDOT() ! 258: { ! 259: ! 260: markpr(dot); ! 261: } ! 262: ! 263: markpr(which) ! 264: line *which; ! 265: { ! 266: ! 267: if ((inglobal == 0 || inopen) && which <= endcore) { ! 268: names['z'-'a'+1] = *which & ~01; ! 269: if (inopen) ! 270: ncols['z'-'a'+1] = cursor; ! 271: } ! 272: } ! 273: ! 274: markreg(c) ! 275: register int c; ! 276: { ! 277: ! 278: if (c == '\'' || c == '`') ! 279: return ('z' + 1); ! 280: if (c >= 'a' && c <= 'z') ! 281: return (c); ! 282: return (0); ! 283: } ! 284: ! 285: /* ! 286: * Mesg decodes the terse/verbose strings. Thus ! 287: * 'xxx@yyy' -> 'xxx' if terse, else 'xxx yyy' ! 288: * 'xxx|yyy' -> 'xxx' if terse, else 'yyy' ! 289: * All others map to themselves. ! 290: */ ! 291: char * ! 292: mesg(str) ! 293: register char *str; ! 294: { ! 295: register char *cp; ! 296: ! 297: str = strcpy(genbuf, str); ! 298: for (cp = str; *cp; cp++) ! 299: switch (*cp) { ! 300: ! 301: case '@': ! 302: if (value(TERSE)) ! 303: *cp = 0; ! 304: else ! 305: *cp = ' '; ! 306: break; ! 307: ! 308: case '|': ! 309: if (value(TERSE) == 0) ! 310: return (cp + 1); ! 311: *cp = 0; ! 312: break; ! 313: } ! 314: return (str); ! 315: } ! 316: ! 317: /*VARARGS2*/ ! 318: merror(seekpt, i) ! 319: #ifdef VMUNIX ! 320: char *seekpt; ! 321: #else ! 322: # ifdef lint ! 323: char *seekpt; ! 324: # else ! 325: int seekpt; ! 326: # endif ! 327: #endif ! 328: int i; ! 329: { ! 330: register char *cp = linebuf; ! 331: ! 332: if (seekpt == 0) ! 333: return; ! 334: merror1(seekpt); ! 335: if (*cp == '\n') ! 336: putnl(), cp++; ! 337: if (inopen && CE) ! 338: vclreol(); ! 339: if (SO && SE) ! 340: putpad(SO); ! 341: printf(mesg(cp), i); ! 342: if (SO && SE) ! 343: putpad(SE); ! 344: } ! 345: ! 346: merror1(seekpt) ! 347: #ifdef VMUNIX ! 348: char *seekpt; ! 349: #else ! 350: # ifdef lint ! 351: char *seekpt; ! 352: # else ! 353: int seekpt; ! 354: # endif ! 355: #endif ! 356: { ! 357: ! 358: #ifdef VMUNIX ! 359: strcpy(linebuf, seekpt); ! 360: #else ! 361: lseek(erfile, (long) seekpt, 0); ! 362: if (read(erfile, linebuf, 128) < 2) ! 363: CP(linebuf, "ERROR"); ! 364: #endif ! 365: } ! 366: ! 367: morelines() ! 368: { ! 369: ! 370: if ((int) sbrk(1024 * sizeof (line)) == -1) ! 371: return (-1); ! 372: endcore += 1024; ! 373: return (0); ! 374: } ! 375: ! 376: nonzero() ! 377: { ! 378: ! 379: if (addr1 == zero) { ! 380: notempty(); ! 381: error("Nonzero address required@on this command"); ! 382: } ! 383: } ! 384: ! 385: notable(i) ! 386: int i; ! 387: { ! 388: ! 389: return (hush == 0 && !inglobal && i > value(REPORT)); ! 390: } ! 391: ! 392: ! 393: notempty() ! 394: { ! 395: ! 396: if (dol == zero) ! 397: error("No lines@in the buffer"); ! 398: } ! 399: ! 400: ! 401: netchHAD(cnt) ! 402: int cnt; ! 403: { ! 404: ! 405: netchange(lineDOL() - cnt); ! 406: } ! 407: ! 408: netchange(i) ! 409: register int i; ! 410: { ! 411: register char *cp; ! 412: ! 413: if (i > 0) ! 414: notesgn = cp = "more "; ! 415: else ! 416: notesgn = cp = "fewer ", i = -i; ! 417: if (inopen) { ! 418: notecnt = i; ! 419: notenam = ""; ! 420: return; ! 421: } ! 422: if (!notable(i)) ! 423: return; ! 424: printf(mesg("%d %slines@in file after %s"), i, cp, Command); ! 425: putNFL(); ! 426: } ! 427: ! 428: putmark(addr) ! 429: line *addr; ! 430: { ! 431: ! 432: putmk1(addr, putline()); ! 433: } ! 434: ! 435: putmk1(addr, n) ! 436: register line *addr; ! 437: int n; ! 438: { ! 439: register line *markp; ! 440: ! 441: *addr &= ~1; ! 442: for (markp = (anymarks ? names : &names['z'-'a'+1]); ! 443: markp <= &names['z'-'a'+1]; markp++) ! 444: if (*markp == *addr) ! 445: *markp = n; ! 446: *addr = n; ! 447: } ! 448: ! 449: char * ! 450: plural(i) ! 451: long i; ! 452: { ! 453: ! 454: return (i == 1 ? "" : "s"); ! 455: } ! 456: ! 457: int qcount(); ! 458: short vcntcol; ! 459: ! 460: qcolumn(lim, gp) ! 461: register char *lim, *gp; ! 462: { ! 463: register int x; ! 464: int (*OO)(); ! 465: ! 466: OO = Outchar; ! 467: Outchar = qcount; ! 468: vcntcol = 0; ! 469: if (lim != NULL) ! 470: x = lim[1], lim[1] = 0; ! 471: pline(0); ! 472: if (lim != NULL) ! 473: lim[1] = x; ! 474: if (gp) ! 475: while (*gp) ! 476: putchar(*gp++); ! 477: Outchar = OO; ! 478: return (vcntcol); ! 479: } ! 480: ! 481: int ! 482: qcount(c) ! 483: int c; ! 484: { ! 485: ! 486: if (c == '\t') { ! 487: vcntcol += value(TABSTOP) - vcntcol % value(TABSTOP); ! 488: return; ! 489: } ! 490: vcntcol++; ! 491: } ! 492: ! 493: reverse(a1, a2) ! 494: register line *a1, *a2; ! 495: { ! 496: register line t; ! 497: ! 498: for (;;) { ! 499: t = *--a2; ! 500: if (a2 <= a1) ! 501: return; ! 502: *a2 = *a1; ! 503: *a1++ = t; ! 504: } ! 505: } ! 506: ! 507: save(a1, a2) ! 508: line *a1; ! 509: register line *a2; ! 510: { ! 511: register int more; ! 512: ! 513: undkind = UNDNONE; ! 514: undadot = dot; ! 515: more = (a2 - a1 + 1) - (unddol - dol); ! 516: while (more > (endcore - truedol)) ! 517: if (morelines() < 0) ! 518: error("Out of memory@saving lines for undo - try using ed or re"); ! 519: if (more) ! 520: (*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1, ! 521: (truedol - unddol)); ! 522: unddol += more; ! 523: truedol += more; ! 524: copyw(dol + 1, a1, a2 - a1 + 1); ! 525: undkind = UNDALL; ! 526: unddel = a1 - 1; ! 527: undap1 = a1; ! 528: undap2 = a2 + 1; ! 529: } ! 530: ! 531: save12() ! 532: { ! 533: ! 534: save(addr1, addr2); ! 535: } ! 536: ! 537: saveall() ! 538: { ! 539: ! 540: save(one, dol); ! 541: } ! 542: ! 543: span() ! 544: { ! 545: ! 546: return (addr2 - addr1 + 1); ! 547: } ! 548: ! 549: sync() ! 550: { ! 551: ! 552: chng = 0; ! 553: tchng = 0; ! 554: xchng = 0; ! 555: } ! 556: ! 557: ! 558: skipwh() ! 559: { ! 560: register int wh; ! 561: ! 562: wh = 0; ! 563: while (iswhite(peekchar())) { ! 564: wh++; ! 565: ignchar(); ! 566: } ! 567: return (wh); ! 568: } ! 569: ! 570: /*VARARGS2*/ ! 571: smerror(seekpt, cp) ! 572: #ifdef lint ! 573: char *seekpt; ! 574: #else ! 575: int seekpt; ! 576: #endif ! 577: char *cp; ! 578: { ! 579: ! 580: if (seekpt == 0) ! 581: return; ! 582: merror1(seekpt); ! 583: if (inopen && CE) ! 584: vclreol(); ! 585: if (SO && SE) ! 586: putpad(SO); ! 587: lprintf(mesg(linebuf), cp); ! 588: if (SO && SE) ! 589: putpad(SE); ! 590: } ! 591: ! 592: #define std_nerrs (sizeof std_errlist / sizeof std_errlist[0]) ! 593: ! 594: #define error(i) i ! 595: ! 596: #ifdef lint ! 597: char *std_errlist[] = { ! 598: #else ! 599: #ifdef VMUNIX ! 600: char *std_errlist[] = { ! 601: #else ! 602: short std_errlist[] = { ! 603: #endif ! 604: #endif ! 605: error("Error 0"), ! 606: error("Not super-user"), ! 607: error("No such file or directory"), ! 608: error("No such process"), ! 609: error("Interrupted system call"), ! 610: error("Physical I/O error"), ! 611: error("No such device or address"), ! 612: error("Argument list too long"), ! 613: error("Exec format error"), ! 614: error("Bad file number"), ! 615: error("No children"), ! 616: error("No more processes"), ! 617: error("Not enough core"), ! 618: error("Permission denied"), ! 619: error("Bad address"), ! 620: error("Block device required"), ! 621: error("Mount device busy"), ! 622: error("File exists"), ! 623: error("Cross-device link"), ! 624: error("No such device"), ! 625: error("Not a directory"), ! 626: error("Is a directory"), ! 627: error("Invalid argument"), ! 628: error("File table overflow"), ! 629: error("Too many open files"), ! 630: error("Not a typewriter"), ! 631: error("Text file busy"), ! 632: error("File too large"), ! 633: error("No space left on device"), ! 634: error("Illegal seek"), ! 635: error("Read-only file system"), ! 636: error("Too many links"), ! 637: error("Broken pipe") ! 638: #ifndef QUOTA ! 639: , error("Math argument") ! 640: , error("Result too large") ! 641: #else ! 642: , error("Quota exceeded") ! 643: #endif ! 644: }; ! 645: ! 646: #undef error ! 647: ! 648: char * ! 649: strend(cp) ! 650: register char *cp; ! 651: { ! 652: ! 653: while (*cp) ! 654: cp++; ! 655: return (cp); ! 656: } ! 657: ! 658: strcLIN(dp) ! 659: char *dp; ! 660: { ! 661: ! 662: CP(linebuf, dp); ! 663: } ! 664: ! 665: syserror() ! 666: { ! 667: register int e = errno; ! 668: ! 669: dirtcnt = 0; ! 670: putchar(' '); ! 671: if (e >= 0 && errno <= std_nerrs) ! 672: error(std_errlist[e]); ! 673: else ! 674: error("System error %d", e); ! 675: } ! 676: ! 677: char * ! 678: vfindcol(i) ! 679: int i; ! 680: { ! 681: register char *cp; ! 682: register int (*OO)() = Outchar; ! 683: ! 684: Outchar = qcount; ! 685: ignore(qcolumn(linebuf - 1, NOSTR)); ! 686: for (cp = linebuf; *cp && vcntcol < i; cp++) ! 687: putchar(*cp); ! 688: if (cp != linebuf) ! 689: cp--; ! 690: Outchar = OO; ! 691: return (cp); ! 692: } ! 693: ! 694: char * ! 695: vskipwh(cp) ! 696: register char *cp; ! 697: { ! 698: ! 699: while (iswhite(*cp) && cp[1]) ! 700: cp++; ! 701: return (cp); ! 702: } ! 703: ! 704: ! 705: char * ! 706: vpastwh(cp) ! 707: register char *cp; ! 708: { ! 709: ! 710: while (iswhite(*cp)) ! 711: cp++; ! 712: return (cp); ! 713: } ! 714: ! 715: whitecnt(cp) ! 716: register char *cp; ! 717: { ! 718: register int i; ! 719: ! 720: i = 0; ! 721: for (;;) ! 722: switch (*cp++) { ! 723: ! 724: case '\t': ! 725: i += value(TABSTOP) - i % value(TABSTOP); ! 726: break; ! 727: ! 728: case ' ': ! 729: i++; ! 730: break; ! 731: ! 732: default: ! 733: return (i); ! 734: } ! 735: } ! 736: ! 737: #ifdef lint ! 738: Ignore(a) ! 739: char *a; ! 740: { ! 741: ! 742: a = a; ! 743: } ! 744: ! 745: Ignorf(a) ! 746: int (*a)(); ! 747: { ! 748: ! 749: a = a; ! 750: } ! 751: #endif ! 752: ! 753: markit(addr) ! 754: line *addr; ! 755: { ! 756: ! 757: if (addr != dot && addr >= one && addr <= dol) ! 758: markDOT(); ! 759: } ! 760:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.