|
|
1.1 ! root 1: #include <stdio.h> ! 2: #ifdef ux3 ! 3: #include <termio.h> ! 4: #else ! 5: #include <sgtty.h> ! 6: #endif ! 7: /* EMACS_MODES: c !fill */ ! 8: char *getenv(); ! 9: /* macro definitions */ ! 10: ! 11: #define EOL '\n' ! 12: ! 13: char *UP; /* cursor up line */ ! 14: char *DOWN; ! 15: char *BACK; ! 16: char *FORWARD; ! 17: char *HOME; ! 18: char *CLEAR; ! 19: char *CLREST; ! 20: char *CLINE; ! 21: char *BELL; ! 22: char *CURAD; ! 23: char *TMAP; ! 24: char *SMAP; ! 25: char *NOP; ! 26: char *LOPEN; ! 27: char *LDEL; ! 28: char *INSERTC; ! 29: char *INSERTM; ! 30: char *OSERTC; ! 31: char *INSERTP; ! 32: char *DELC; ! 33: char *SSCROLL; ! 34: char *RSCROLL; ! 35: char *CR; ! 36: char *SCREG; ! 37: char *ULINE; ! 38: char *UEND; ! 39: int EOVER; ! 40: char *SCINIT; ! 41: char *VEXIT; ! 42: char *RELDOWN; ! 43: char *RELUP; ! 44: char *RELFORW; ! 45: char *RELBACK; ! 46: int XBASE; ! 47: int YBASE; ! 48: int SCRWID; ! 49: int SCRNLIN; ! 50: int SCRWRAP; ! 51: int VCOST; ! 52: int SRCADD; ! 53: int MI; ! 54: int IN; ! 55: int DELMODE; ! 56: ! 57: /* character definitions */ ! 58: ! 59: #define META 0200 ! 60: #define MTA(mtach) ('mtach'+0200) /* make meta char */ ! 61: #define ESC 033 ! 62: #define NEWLINE 037 ! 63: #define RUB 0177 ! 64: ! 65: /* DISPLAY MODE PARAMETERS */ ! 66: ! 67: int WRAPON = 0; /* perform ! processing at EOL */ ! 68: int INSON = 0; /* use INSERTC/DELC */ ! 69: ! 70: /* screen display data */ ! 71: ! 72: char ttobuf[BUFSIZ]; ! 73: ! 74: int drain; ! 75: int mline; ! 76: int mcol; ! 77: int SCRLINES; /* number of lines in window */ ! 78: int ECHOL; /* line for prompting */ ! 79: int MODLN; /* line for buffer and file data */ ! 80: ! 81: ! 82: ! 83: /* statistics */ ! 84: ! 85: long nmput; /* calls to mputc */ ! 86: long noutc; /* actual characters output */ ! 87: int ninch; /* number of characters input */ ! 88: int ntwrite; /* number of terminal writes */ ! 89: int nbwrite; /* number of buffer writes */ ! 90: int nbseek; /* number of seeks of buffer */ ! 91: int nbread; /* number of buffer reads */ ! 92: int nmkline; /* number of makeline calls */ ! 93: ! 94: extern int errno; ! 95: ! 96: /* function definitions */ ! 97: ! 98: char *getname(); ! 99: /*VARARGS*/ char *execl(); ! 100: ! 101: /* lint definitions */ ! 102: ! 103: #ifdef lint ! 104: #define IGNORE(x) if(x); ! 105: #else ! 106: #define IGNORE(x) (x) ! 107: #endif ! 108: ! 109: /* emacs display definitions */ ! 110: ! 111: ! 112: /* EMACS_MODES: c !fill */ ! 113: ! 114: char ldchar; /* last clobbered character */ ! 115: char ldcol; /* collumn of ldchar */ ! 116: char osert = 0; /* flag indicating insert char mode */ ! 117: int acost; /* cost of absolute positioning */ ! 118: int lUP; /* cost of UP */ ! 119: int lDOWN; /* cost of DOWN */ ! 120: int lBAK; /* cost of BACK */ ! 121: int lCR; ! 122: ! 123: int psx; ! 124: int psy; ! 125: int saveline; ! 126: int savecol; ! 127: int scrlin; ! 128: int scrcol; ! 129: int ttywarp; /* tty warp factor (stty speed) */ ! 130: ! 131: /* display data */ ! 132: ! 133: #define TTYLEN 256 /* total area for tty data strings */ ! 134: char ttystrings[TTYLEN]; ! 135: ! 136: ! 137: struct sparm { ! 138: char *t_pname; ! 139: int *t_padd; ! 140: }; ! 141: ! 142: struct sparm ttydata[] = { ! 143: "up",(int *) &UP, ! 144: "do",(int *) &DOWN, ! 145: "bc",(int *) &BACK, ! 146: "nd",(int *) &FORWARD, ! 147: "ho",(int *) &HOME, ! 148: "cl",(int *) &CLEAR, ! 149: "cd",(int *) &CLREST, ! 150: "ce",(int *) &CLINE, ! 151: "bl",(int *) &BELL, ! 152: "cm",(int *) &CURAD, ! 153: "tm",(int *) &TMAP, ! 154: "tM",(int *) &SMAP, ! 155: "pc",(int *) &NOP, ! 156: "al",(int *) &LOPEN, ! 157: "dl",(int *) &LDEL, ! 158: "ic",(int *) &INSERTC, ! 159: "im",(int *) &INSERTM, ! 160: "ei",(int *) &OSERTC, ! 161: "ip",(int *) &INSERTP, ! 162: "dc",(int *) &DELC, ! 163: "sf",(int *) &SSCROLL, ! 164: "sr",(int *) &RSCROLL, ! 165: "cr",(int *) &CR, ! 166: "cs",(int *) &SCREG, ! 167: "ul",(int *) &ULINE, ! 168: "ue",(int *) &UEND, ! 169: "eo",&EOVER, ! 170: "vs",(int *) &SCINIT, ! 171: "ve",(int *) &VEXIT, ! 172: "bx",&XBASE, ! 173: "by",&YBASE, ! 174: "co",&SCRWID, ! 175: "li",&SCRNLIN, ! 176: "am",&SCRWRAP, ! 177: "vc",(int *) &VCOST, ! 178: "rc",(int *) &SRCADD, ! 179: "mi",(int *) &MI, ! 180: "in",(int *) &IN, ! 181: "dm",&DELMODE, ! 182: "ru",(int *) &RELUP, ! 183: "rd",(int *) &RELDOWN, ! 184: "rl",(int *) &RELFORW, ! 185: "rr",(int *) &RELBACK, ! 186: 0,0, ! 187: }; ! 188: ! 189: char *endput = "____________________"; ! 190: ! 191: ! 192: ! 193: #define SCRCONT '!' ! 194: int TABSTOP = 8; ! 195: ! 196: #define NSCRLIN 48 /* max screen lines */ ! 197: #define NSCRCOL 128 /* max screen columns */ ! 198: char cmap[NSCRLIN] [NSCRCOL]; ! 199: int scrjnk[NSCRLIN]; /* column of last non-white character */ ! 200: ! 201: ! 202: ! 203: /* character type table */ ! 204: ! 205: #define PLAIN 0 ! 206: #define CONTRL 1 ! 207: #define TAB 2 ! 208: #define BACKSP 3 ! 209: ! 210: char ctype[128] = { ! 211: CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, ! 212: BACKSP, TAB, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, ! 213: CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, ! 214: CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, ! 215: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 216: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 217: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 218: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 219: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 220: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 221: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 222: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 223: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 224: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 225: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, ! 226: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, CONTRL, ! 227: }; ! 228: ! 229: ! 230: /* display heuristics */ ! 231: ! 232: #define CFILL 30 /* average chars/line */ ! 233: #define PATIENCE 2000 /* number of millisecends of */ ! 234: /* output to buffer before */ ! 235: /* looking for type ahead */ ! 236: ! 237: ! 238: /* display macros */ ! 239: ! 240: #define mputc(chr) (((mcol<scrjnk[mline]) && (chr == cmap[mline][mcol]))? mcol++ : mptc(chr)) ! 241: ! 242: /* trace stuff */ ! 243: ! 244: ! 245: char *termdir = SDIR/terminals/%s"; ! 246: ! 247: ! 248: /* Terminal I/O modes, sgttyb for before unix 3.0, termio for later */ ! 249: ! 250: int SREGION = 24; ! 251: ! 252: #ifdef ux3 ! 253: struct termio ttyjunk; ! 254: #else ! 255: struct sgttyb ttyjunk; ! 256: #endif ! 257: ! 258: int ttyerase = '#'; ! 259: int ttykill = '@'; ! 260: int ttyintr = ''; ! 261: int ttyeof = ''; ! 262: ! 263: #define NBAUD 16 /* number of baud rates */ ! 264: char charms[NBAUD] = { /* ms per char in various rates */ ! 265: 100, ! 266: 100, /* 50 */ ! 267: 100, /* 75 */ ! 268: 100, /* 110 */ ! 269: 70, /* 134 */ ! 270: 66, /* 150 */ ! 271: 50, /* 200 */ ! 272: 33, /* 300 */ ! 273: 16, /* 600 */ ! 274: 8, /* 1200 */ ! 275: 5, /* 1800 */ ! 276: 4, /* 2400 */ ! 277: 2, /* 4800 */ ! 278: 1, /* 9600 */ ! 279: 1, /* EXTA */ ! 280: 1, /* EXTB */ ! 281: }; ! 282: ! 283: xgo(x,y) ! 284: ! 285: { ! 286: ldchar = 0; ! 287: mline = x; ! 288: mcol = y; ! 289: } ! 290: ! 291: ! 292: /* beep -- obvious */ ! 293: ! 294: beep() ! 295: ! 296: { ! 297: PUTS(BELL); /* print a bell */ ! 298: } ! 299: ! 300: /* move both the display matrix pointer and the actual display to the ! 301: * specified line and column */ ! 302: ! 303: mgo(x,y) ! 304: ! 305: register x,y; ! 306: ! 307: { ! 308: ! 309: sgo(mline = x,mcol = y); ! 310: } ! 311: ! 312: ! 313: /* move the display cursor to the specified destination. sgo attempts ! 314: * to optimize the movement, using single character or absolute ! 315: * positioning */ ! 316: ! 317: sgo(x,y) ! 318: ! 319: register x,y; ! 320: ! 321: { ! 322: int mx,my; ! 323: int xcost; /* cost with all relative movement */ ! 324: int ycost; /* cost with carriage return */ ! 325: /* acost is cost of absolute positioning */ ! 326: ! 327: /* calculate relative costs of various movements. cost functions */ ! 328: /* automatically indicate that un-doable motions have infinite cost */ ! 329: ! 330: ! 331: ! 332: ! 333: /* calculate xcost and ycost */ ! 334: ! 335: mx = x-scrlin; ! 336: if (mx<0) { ! 337: mx = -mx; ! 338: xcost = mx*lUP; ! 339: } else xcost = mx*lDOWN; ! 340: ! 341: ycost = y + xcost + lCR; ! 342: ! 343: my = y-scrcol; ! 344: if (my<0) { ! 345: my = -my; ! 346: xcost +=my*lBAK; ! 347: } else xcost += my; ! 348: ! 349: ! 350: if (acost < ycost) { ! 351: if (acost < xcost) { ! 352: /* do absolute positioning */ ! 353: if (CURAD) { /* have absolute addrs */ ! 354: if (SRCADD) { ! 355: eprintf(CURAD,x+XBASE,y+YBASE); ! 356: } else { ! 357: eprintf(CURAD,y+YBASE,x+XBASE); ! 358: } ! 359: } else { /* have relative addrs */ ! 360: if (x>scrlin) printf (RELDOWN,mx); ! 361: if (x<scrlin) printf (RELUP,mx); ! 362: if (y>scrcol) printf (RELFORW,my); ! 363: if (y<scrcol) printf (RELBACK,my); ! 364: } ! 365: scrlin=x; ! 366: scrcol=y; ! 367: return; ! 368: } /* else relative is cheap, do it */ ! 369: } else { ! 370: if (osert && (MI == 0)) { ! 371: unsert(); ! 372: } ! 373: if (ycost < xcost) { /* do carriage return processing */ ! 374: PUTS(CR); /* carriage return */ ! 375: scrcol = 0; ! 376: /* fall through to finish with relative motion */ ! 377: } ! 378: } ! 379: ! 380: while (x != scrlin) { ! 381: if (x < scrlin) { ! 382: PUTS(UP); ! 383: scrlin--; ! 384: } else { ! 385: PUTS(DOWN); ! 386: scrlin++; ! 387: } ! 388: } ! 389: ! 390: /* now correct row */ ! 391: ! 392: while (y != scrcol) { ! 393: if (y < scrcol) { ! 394: PUTS(BACK); ! 395: scrcol--; ! 396: } else { ! 397: if (FORWARD == NULL) { ! 398: if (osert) { ! 399: unsert(); ! 400: } ! 401: x = cmap[scrlin] [scrcol]; ! 402: if ((x == 0)|| (scrjnk[scrlin]<=scrcol)) x=cmap[scrlin] [scrcol] = ' '; ! 403: putit(x); /* re-write */ ! 404: } else { ! 405: PUTS(FORWARD); ! 406: } ! 407: scrcol++; ! 408: } ! 409: }; ! 410: return; ! 411: } ! 412: ! 413: /* unsert -- LEAVE insert character mode */ ! 414: ! 415: unsert() ! 416: { ! 417: eprintf(OSERTC); /* can't stay inserting */ ! 418: osert = 0; ! 419: } ! 420: ! 421: /* a simple guide to all of the various putc routines in this program: ! 422: * xputc puts a character out, translating control and meta characters ! 423: * to prefix sequences, and calling sputc to put out the individual ! 424: * characters. sputc checks for end of line, and if so wraps to the ! 425: * next line. sputc calls mputc to output characters. mputc updates ! 426: * the next character in the display to be whaat is put out. Display ! 427: * takes place only if the character on the screen is not that called for ! 428: * already. */ ! 429: ! 430: ! 431: mptc(c) ! 432: register c; ! 433: { ! 434: nmput++; /* count for stats */ ! 435: if ((c == ' ') && (mcol >= scrjnk[mline])) { ! 436: ! 437: cmap[mline] [mcol++] = c; ! 438: return; ! 439: } ! 440: if ((mcol != scrcol) || (mline != scrlin)) sgo(mline,mcol); ! 441: if (DELC && INSON && (c == cmap [mline] [mcol+1]) && (mcol+3 <scrjnk[mline]) && (ldchar == 0)) { ! 442: register i; ! 443: SREGION=scrjnk[mline]-mcol; /* number of char's gobbled */ ! 444: if (DELMODE && (osert == 0)) { ! 445: eprintf(INSERTM); ! 446: osert++; ! 447: } ! 448: eprintf(DELC); /*clobber next char */ ! 449: for (i = mcol; i <=scrjnk[mline];i++) { ! 450: cmap[mline] [i] = cmap[mline] [i+1]; ! 451: } ! 452: scrjnk[mline]--; ! 453: } else { ! 454: if ((INSERTC || INSERTM) && INSON && (c == ldchar) && (mcol == ldcol+1) && (mcol<scrjnk[mline])) { ! 455: register i; ! 456: if (INSERTM && (osert == 0)) { ! 457: eprintf(INSERTM); /* open space */ ! 458: osert = 1; ! 459: } ! 460: if (scrjnk[mline] >SCRWID) scrjnk[mline]--; ! 461: for (i = scrjnk[mline]++; i >= mcol;i--) { ! 462: cmap[mline] [i+1] = cmap[mline] [i]; ! 463: } ! 464: if (INSERTC) eprintf(INSERTC); ! 465: cmap[mline] [mcol] = 0; ! 466: } else { ! 467: if (osert) { ! 468: unsert(); ! 469: } ! 470: } ! 471: putit(c); ! 472: if (osert && INSERTP) eprintf(INSERTP); ! 473: if (ldchar == 0) ldcol = mcol; /* remember where it was */ ! 474: ldchar = cmap[mline][mcol]; /* save last clobber */ ! 475: if ((scrcol++ >= SCRWID) && SCRWRAP) { ! 476: scrlin++; ! 477: scrcol=0; ! 478: } ! 479: } ! 480: cmap[mline] [mcol] = c; ! 481: while (scrjnk[mline] <mcol) cmap[mline] [scrjnk[mline]++] = ' '; ! 482: if (++mcol> scrjnk[mline]) scrjnk[mline] = mcol; ! 483: } ! 484: ! 485: /* getname prompts for a string, using ps, and inputs a string */ ! 486: ! 487: /* rubout and @ can be used to edit the string as enterred, and causes ! 488: * a quit, returning no input string ! 489: * ^Y causes the current buffer name to be brought out ! 490: */ ! 491: #define FNLEN 128 ! 492: char fnbuf[FNLEN]; ! 493: ! 494: ! 495: char * ! 496: getname(ps) ! 497: ! 498: register char *ps; ! 499: ! 500: { ! 501: register i; ! 502: register char c; ! 503: char *xp; ! 504: ! 505: fnbuf[i=0] = 0; ! 506: for (;;) { ! 507: prompt1("%s%s",ps,fnbuf); /* display prompt */ ! 508: mgo(mline,mcol); ! 509: c = mgetchar(); ! 510: ! 511: if ((c == '') || (c == ttyintr)) { ! 512: beep(); ! 513: unprompt(); ! 514: return(NULL); ! 515: } ! 516: if ((c == ' ') || (c == '\n')) { ! 517: unprompt(); ! 518: return(fnbuf); ! 519: } ! 520: if (c == ttyerase) { ! 521: if (i) { ! 522: i--; ! 523: fnbuf[i] = 0; ! 524: } else beep(); ! 525: continue; ! 526: } ! 527: if (c == ttykill) { ! 528: fnbuf[i=0]=0; ! 529: continue; ! 530: } ! 531: if (c == '') { ! 532: c = 0177 & getchar(); ! 533: } ! 534: fnbuf[i++] = c; ! 535: if (i >= FNLEN) { ! 536: beep(); ! 537: --i; ! 538: } ! 539: fnbuf[i] = 0; ! 540: continue; ! 541: } ! 542: } ! 543: ! 544: /* putout outputs a string (like eprintf) at the current position */ ! 545: ! 546: /* position is advanced one line. If the position overflows the screen, ! 547: * -MORE- is printed, and input is read. Any character except ^G ! 548: * continues the display, ^G quits by returning -1 */ ! 549: ! 550: /*VARARGS1*/ ! 551: ! 552: putout(string,arg1,arg2,arg3,arg4,arg5,arg6) ! 553: char *string; ! 554: { ! 555: if (mline>=SCRLINES) { ! 556: prompt1("-- MORE --"); ! 557: if ((mgetchar()) == ttykill) return(-1); ! 558: unprompt(); ! 559: mline=0; /* TOP */ ! 560: } ! 561: prompt(mline,string,arg1,arg2,arg3,arg4,arg5,arg6); ! 562: clrl(); ! 563: mgo(++mline,0); ! 564: return(0); ! 565: } ! 566: ! 567: /* put out a string on ECHOL */ ! 568: /*VARARGS1*/ ! 569: ! 570: prompt1(string,arg1,arg2,arg3,arg4,arg5) ! 571: char *string; ! 572: { ! 573: prompt(ECHOL,string,arg1,arg2,arg3,arg4,arg5); ! 574: } ! 575: ! 576: /* put out a string at a specified line */ ! 577: ! 578: /*VARARGS2*/ ! 579: ! 580: prompt(ecl,string,arg1,arg2,arg3,arg4,arg5,arg6) ! 581: ! 582: char *string; ! 583: register int ecl; ! 584: ! 585: { ! 586: char pbuf[256]; ! 587: ! 588: if (mline<=SCRLINES) { ! 589: saveline = mline; ! 590: savecol = mcol; ! 591: } ! 592: mline = ecl; ! 593: mcol = 0; ! 594: seprintf(pbuf,string,arg1,arg2,arg3,arg4,arg5,arg6); ! 595: sputs(pbuf); ! 596: psx = mline; ! 597: psy = mcol; ! 598: clrl(); ! 599: } ! 600: ! 601: /* clear out prompt */ ! 602: ! 603: unprompt() ! 604: ! 605: { ! 606: ! 607: if (mline<=SCRLINES) { /* if position to save */ ! 608: saveline = mline; ! 609: savecol = mcol; ! 610: } ! 611: mgo(ECHOL,0); ! 612: clrl(); ! 613: mgo(saveline,savecol); ! 614: } ! 615: ! 616: ! 617: /* return to the position saved before the last prompt */ ! 618: ! 619: goback() ! 620: ! 621: { ! 622: mgo(saveline,savecol); ! 623: } ! 624: ! 625: /* put one character on the screen checking for end of screen line */ ! 626: ! 627: sputc(c) ! 628: ! 629: register c; ! 630: { ! 631: ! 632: register i; ! 633: ! 634: if (mcol == SCRWID) { ! 635: if (WRAPON) { ! 636: if (mline>=NSCRLIN-1) { ! 637: mline--; /* don't run overboard */ ! 638: } else { ! 639: mputc(SCRCONT); ! 640: mline++; ! 641: } ! 642: ldchar = 0; /* reset ldchar */ ! 643: mcol = 0; ! 644: } else { ! 645: mputc(c); ! 646: mline++; ! 647: mcol=0; ! 648: ldchar=0; ! 649: return; ! 650: } ! 651: } ! 652: mputc(c); ! 653: } ! 654: ! 655: /* put one character in the display, checking for control and meta chars. */ ! 656: ! 657: xputc(c) ! 658: register c; ! 659: { ! 660: register i; ! 661: ! 662: c &= 0377; ! 663: if (c & META) { ! 664: sputc('M'); ! 665: sputc('-'); ! 666: c-= META; ! 667: } ! 668: switch(ctype[c]) { ! 669: char oc; ! 670: case PLAIN: ! 671: if ((!ULINE)||(!EOVER)) { ! 672: sputc(c); ! 673: return; ! 674: } ! 675: if (scrjnk[mline] <= mcol) { ! 676: sputc(c); ! 677: return; ! 678: } ! 679: oc = cmap[mline][mcol] & 0177 ; ! 680: if ((oc == '_') && ((c & 0177) != ' ') ! 681: && ((c & 0177) != '_')) { ! 682: sputc(0200 | c); ! 683: return; ! 684: } ! 685: sputc(c); ! 686: return; ! 687: case BACKSP: ! 688: if ((ULINE)&&(EOVER)) { ! 689: if (mcol != 0) xgo(mline,mcol-1); ! 690: return; ! 691: } ! 692: /* NO BREAK HERE */ ! 693: case CONTRL: ! 694: sputc('^'); ! 695: sputc(c^0100); ! 696: return; ! 697: ! 698: case TAB: ! 699: i = TABSTOP-(mcol%TABSTOP); ! 700: while (i--) sputc(' '); ! 701: return; ! 702: ! 703: } ! 704: } ! 705: ! 706: ! 707: ! 708: /* clear the rest of the line, checking to see if the line previously ! 709: * displayed corresponds to the one displayed here now */ ! 710: ! 711: clrl() ! 712: ! 713: { ! 714: register x; ! 715: register y; ! 716: register z; ! 717: int xline; ! 718: int xcol; ! 719: ! 720: ldchar = 0; /* wipe out last char */ ! 721: x = mline; ! 722: z = mcol; ! 723: y = scrjnk[mline] - mcol; ! 724: if (y > 0) { ! 725: sgo(mline,mcol); /* go for real */ ! 726: if (CLINE) { ! 727: SREGION=y; /* Number of characters cleared */ ! 728: eprintf(CLINE); ! 729: } else { ! 730: xline = mline; ! 731: xcol = mcol; ! 732: while (y--) mputc (' '); ! 733: mgo(xline,xcol); ! 734: } ! 735: scrjnk[x] = z; ! 736: } ! 737: } ! 738: ! 739: /* put a string on the screen, translating control and meta */ ! 740: ! 741: sputs(xp) ! 742: register char *xp; ! 743: { ! 744: register c; ! 745: while (c= *xp++) { ! 746: if (c == NEWLINE) { ! 747: if (mline < NSCRLIN) mline++; /* don't overflow */ ! 748: mcol = 0; ! 749: xputc(' '); ! 750: } else xputc(c); ! 751: } ! 752: } ! 753: ! 754: clear() ! 755: ! 756: { ! 757: register int i; ! 758: ! 759: eprintf(CLEAR); ! 760: for (i = 0; i < NSCRLIN; i++) scrjnk[i] = 0; ! 761: scrlin = scrcol = mline = mcol = 0; ! 762: } ! 763: ! 764: ! 765: /* Refresh the screen. Clears and then restores what we think is there */ ! 766: ! 767: rfrsh() ! 768: { ! 769: register xline; ! 770: register xcol; ! 771: ! 772: eprintf(CLEAR); ! 773: scrlin=scrcol=0; ! 774: ! 775: for (xline = 0; xline < SCRNLIN; xline++) { ! 776: for (xcol = 0; xcol < scrjnk[xline]; xcol++) { ! 777: if (cmap[xline][xcol]) { ! 778: sgo(xline,xcol); ! 779: putit(cmap[xline][xcol]); ! 780: if ((scrcol++ >= SCRWID) && SCRWRAP) { ! 781: scrlin++; ! 782: scrcol=0; ! 783: } ! 784: } ! 785: } ! 786: } ! 787: ldchar = 0; ! 788: } ! 789: ! 790: sdelay(ms) ! 791: ! 792: register int ms; /* milliseconds of delay */ ! 793: { ! 794: register i; ! 795: for (i = 0; i < ms;) { ! 796: PUTS(NOP); /* idle */ ! 797: i+=ttywarp; /* milliseconds/character */ ! 798: } ! 799: } ! 800: ! 801: ttype() /* set terminal type */ ! 802: ! 803: { ! 804: register char *mp; ! 805: ! 806: mp = getname("Terminal Type? "); ! 807: if (mp == NULL) return; ! 808: sttype(mp); ! 809: } ! 810: ! 811: int ttyptr = 0; ! 812: ! 813: /* terminal description file parser: */ ! 814: ! 815: /* terminal description file contains lines with ! 816: ! 817: parameter=data ! 818: ! 819: * where data is either a number of a string */ ! 820: ! 821: ! 822: ttyparse(mp) ! 823: char *mp; ! 824: ! 825: { ! 826: register FILE *file; ! 827: char xbuf[128]; ! 828: char optbuf[128]; ! 829: register char *cp; ! 830: register int c; ! 831: struct sparm *parmp; ! 832: ! 833: int parm; ! 834: ! 835: ! 836: /* find the terminal file and open it */ ! 837: ! 838: seprintf(xbuf,termdir,mp); /* terminal file */ ! 839: ! 840: file = fopen(xbuf,"r"); ! 841: ! 842: if (file == NULL) file = fopen(mp,"r"); ! 843: ! 844: if (file == NULL) { ! 845: eprintf ("Can't use terminal type %s\n", mp); ! 846: return(0); ! 847: } ! 848: ! 849: /* first find what option we are setting */ ! 850: ! 851: nextparm: cp = optbuf; ! 852: while ((c = getc(file)) != '=') { ! 853: if (c == '\n') goto nextparm; /* comment line */ ! 854: if (c == EOF) { ! 855: fclose(file); ! 856: return(1); /* abort during option scan */ ! 857: } ! 858: *cp++=c; ! 859: } ! 860: *cp = 0; ! 861: ! 862: /* look up parameter in parameter table */ ! 863: ! 864: for (parmp = ttydata; parmp->t_pname; parmp++) { ! 865: if ((optbuf[0]==parmp->t_pname[0])&& (optbuf[1]==parmp->t_pname[1])) { ! 866: ! 867: c = getc(file); ! 868: if ((c >= '0') && (c <= '9')) { ! 869: parm = 0; ! 870: while ((c >= '0') && (c <= '9')) { ! 871: parm = 10*parm + (c-'0'); ! 872: c = getc(file); ! 873: } ! 874: *(parmp->t_padd) = parm; ! 875: if (c != EOF) goto nextparm; ! 876: fclose(file); ! 877: return(1); ! 878: } ! 879: *(parmp->t_padd) = ((int) &ttystrings[ttyptr]); ! 880: ! 881: while ((c != EOF) && (c != EOL)) { ! 882: if (c == '\\') { ! 883: c = getc(file); ! 884: if (c == 'n') c = '\n'; ! 885: } ! 886: ! 887: ttystrings[ttyptr++] = c; ! 888: c = getc(file); ! 889: } ! 890: ttystrings[ttyptr++] = 0; ! 891: if (c != EOF) goto nextparm; ! 892: } ! 893: } ! 894: goto nextparm; ! 895: } ! 896: ! 897: PUTS(string) ! 898: ! 899: char *string; ! 900: ! 901: { ! 902: if (!drain) while(*string) putchar(0177 & *string++); ! 903: } ! 904: sttype(mp) ! 905: register char *mp; ! 906: ! 907: { ! 908: register struct sparm *parmp; ! 909: ! 910: /* First, initialize the tty data */ ! 911: ! 912: ! 913: ! 914: ttyptr = 0; ! 915: for (parmp = ttydata; parmp->t_pname; parmp++) { ! 916: *(parmp->t_padd) = 0; ! 917: } ! 918: SCRLINES=20; ! 919: SCRWID=80; /* so we won't bomb */ ! 920: ! 921: if (ttyparse(mp)) { ! 922: ! 923: SCRWID--; ! 924: ! 925: if (SCRNLIN>NSCRLIN) { ! 926: SCRNLIN=NSCRLIN; ! 927: } ! 928: if (SCRWID>NSCRCOL-1) { ! 929: SCRWID=NSCRCOL-1; ! 930: } ! 931: if (VCOST == 0) VCOST = 1; ! 932: SCRLINES = SCRNLIN-4; ! 933: ECHOL = SCRNLIN-1; ! 934: MODLN = SCRNLIN-3; ! 935: ! 936: if (CURAD) { ! 937: acost = dcost(CURAD); ! 938: } else { ! 939: acost = dcost(RELUP)+dcost(RELFORW); ! 940: } ! 941: lUP = dcost(UP); ! 942: lDOWN = dcost(DOWN); ! 943: lBAK = dcost(BACK); ! 944: lCR = dcost(CR); ! 945: if (OSERTC && (INSERTM == 0)) { ! 946: INSERTM=INSERTC; /* old style insert modes */ ! 947: INSERTC=0; ! 948: } ! 949: if (SCREG) LOPEN = SCREG; /* make sure we use SCREG */ ! 950: if ((NOP == NULL) || (*NOP == 0)) NOP = "\200"; /* null pads get lost */ ! 951: ! 952: if (SCINIT) { ! 953: eprintf(SCINIT); /* initialize screen */ ! 954: } ! 955: clear(); ! 956: } ! 957: } ! 958: ! 959: /* dcost -- calculate display cost of a string */ ! 960: ! 961: dcost(sp) ! 962: register char *sp; ! 963: { ! 964: register int dc; ! 965: ! 966: if (sp == NULL) return(1000); /* infinite cost for missing capability */ ! 967: ! 968: dc = 0; ! 969: while (*sp) { ! 970: if (*sp++ != '%') dc++; ! 971: } ! 972: return(dc); ! 973: } ! 974: ! 975: /* yes or no question */ ! 976: /*VARARGS1*/ ! 977: int ! 978: gyn(string,arg1,arg2,arg3) ! 979: ! 980: char *string; ! 981: char *arg1; ! 982: char *arg2; ! 983: char *arg3; ! 984: { ! 985: register char c; ! 986: ! 987: while (1) { ! 988: prompt(ECHOL,string,arg1,arg2,arg3); ! 989: sgo(mline,mcol); ! 990: c = mgetchar(); ! 991: switch(c) { ! 992: ! 993: case 'y': ! 994: case 'Y': ! 995: case ' ': ! 996: return(1); ! 997: case '': /* This is necessary to insure exit */ ! 998: case 'n': ! 999: case 'N': ! 1000: case '': ! 1001: return(0); ! 1002: case '': ! 1003: return(-1); ! 1004: default: ! 1005: prompt(ECHOL-1,"y for yes, n for no, ^G to quit"); ! 1006: } ! 1007: } ! 1008: }; ! 1009: ! 1010: /* mtop -- move to top of display for message output */ ! 1011: ! 1012: mtop() ! 1013: { ! 1014: mgo(0,0); /* for messages */ ! 1015: } ! 1016: ! 1017: uncook() ! 1018: { ! 1019: ! 1020: /* UNIX 3 code thanks to J. Langer and M. Plotnick */ ! 1021: ! 1022: #ifdef ux3 ! 1023: struct termio nttyjunk; ! 1024: ! 1025: ioctl(1, TCGETA, &ttyjunk); ! 1026: nttyjunk=ttyjunk; ! 1027: ! 1028: #ifdef u370 ! 1029: ! 1030: nttyjunk.c_iflag |= (BRKINT|ISTRIP|IGNPAR); ! 1031: nttyjunk.c_iflag &= ! 1032: ~(IGNBRK|IGNPAR|PARMRK|IXON|INLCR|IGNCR|ICRNL|INPCK); ! 1033: /* accept break, no crnl mapping, no ^S^Q */ ! 1034: nttyjunk.c_oflag = 0; /* no delays, no crlf mapping */ ! 1035: nttyjunk.c_cflag |= CS8 ; ! 1036: nttyjunk.c_lflag &= ~(ISIG|ECHO|ICANON); /* no echo, signals, ! 1037: or erase/kill processing */ ! 1038: #else ! 1039: nttyjunk.c_iflag |= (BRKINT|ISTRIP); ! 1040: nttyjunk.c_iflag &= ~(IGNBRK|PARMRK|INLCR|ICRNL|IGNCR|IXON|IXOFF); ! 1041: /* accept break, no crnl mapping, no ^S^Q */ ! 1042: nttyjunk.c_oflag = 0; /* no delays, no crlf mapping */ ! 1043: nttyjunk.c_lflag &= ~(ISIG|ECHO|ICANON); /* no echo, signals, ! 1044: or erase/kill processing */ ! 1045: #endif ! 1046: nttyjunk.c_cc[VMIN] = 1; /* return after every character read */ ! 1047: nttyjunk.c_cc[VTIME] = 1; ! 1048: ttywarp = charms[ttyjunk.c_cflag&CBAUD]; /* milliseconds for character */ ! 1049: ! 1050: ioctl(1, TCSETAW, &nttyjunk); ! 1051: ioctl(1, TCXONC,1); /* Force tty back on */ ! 1052: ! 1053: #else ! 1054: ! 1055: struct sgttyb nttyjunk; ! 1056: ! 1057: gtty (1,&ttyjunk); ! 1058: nttyjunk=ttyjunk; ! 1059: nttyjunk.sg_flags &= (~ECHO); /* it was so SIMPLE in the old days */ ! 1060: nttyjunk.sg_flags |= (RAW); ! 1061: ttywarp = charms[ttyjunk.sg_ospeed]; /* milliseconds for char */ ! 1062: stty(1,&nttyjunk); ! 1063: #endif ! 1064: ! 1065: #ifndef RT ! 1066: ttyerase = ttyjunk.c_cc[VERASE]; ! 1067: ttykill = ttyjunk.c_cc[VKILL]; ! 1068: ttyeof = ttyjunk.c_cc[VEOF]; ! 1069: ttyintr = ttyjunk.c_cc[VINTR]; ! 1070: #else ! 1071: ttyerase = ttyjunk.sg_erase; ! 1072: ttykill = ttyjunk.sg_kill; ! 1073: ttyeof = '\004'; ! 1074: ttyintr = ''; ! 1075: #endif ! 1076: if (VEXIT) eprintf(SCINIT); /* RE-init terminal */ ! 1077: } ! 1078: ! 1079: /* out of raw mode */ ! 1080: ! 1081: cook() ! 1082: { ! 1083: if (VEXIT) eprintf(VEXIT); ! 1084: fflush(stdout); /* force output */ ! 1085: #ifdef ux3 ! 1086: ioctl(1,TCSETAW, &ttyjunk); ! 1087: ioctl(1, TCXONC,1); /* Force tty back on */ ! 1088: #else ! 1089: stty(1,&ttyjunk); ! 1090: #endif ! 1091: } ! 1092: ! 1093: ! 1094: /*VARARGS2*/ ! 1095: ! 1096: char * ! 1097: nscan(stptr,ret) ! 1098: ! 1099: register char *stptr; ! 1100: register int *ret; ! 1101: { ! 1102: register c; ! 1103: ! 1104: *ret = 0; ! 1105: while (((c = *stptr)>='0') && (c <= '9')) { ! 1106: stptr++; ! 1107: *ret = *ret*10+(c-'0'); ! 1108: } ! 1109: return(stptr); ! 1110: } ! 1111: ! 1112: ! 1113: char * ! 1114: strcpy(cp,cp1) ! 1115: ! 1116: register char *cp; ! 1117: register char *cp1; ! 1118: { ! 1119: while (*cp++ = *cp1++); ! 1120: return(cp-1); ! 1121: } ! 1122: ! 1123: seprintf(string,fmt, x1) ! 1124: register char *string; ! 1125: register char *fmt; ! 1126: unsigned x1; ! 1127: { ! 1128: int c; ! 1129: int width; ! 1130: register unsigned int *adx; ! 1131: extern char *strcpy(); ! 1132: ! 1133: adx = &x1; ! 1134: loop: ! 1135: while((c = *fmt++) != '%') { ! 1136: *string++ = c; ! 1137: if(c == '\0') { ! 1138: return; ! 1139: } ! 1140: } ! 1141: width = 0; ! 1142: c = *fmt++; ! 1143: if ((c >= '0') && (c <= '9')) { ! 1144: fmt = nscan(fmt-1,&width); ! 1145: c = *fmt++; ! 1146: } ! 1147: ! 1148: switch(c) { ! 1149: case 'd': ! 1150: case 'D': ! 1151: case 'o': ! 1152: case 'O': ! 1153: { ! 1154: register int b; ! 1155: long n; ! 1156: long n1; ! 1157: register int i; ! 1158: char dstack[20]; ! 1159: ! 1160: b = (((c=='o') || (c == 'O'))? 8: 10); /* number base */ ! 1161: if ((c == 'o') || (c == 'd')) { ! 1162: n = (long) (*adx); ! 1163: if (n > 32768L) n = n-65536L; /* sign correction */ ! 1164: } else { ! 1165: n = *((long *) adx); ! 1166: adx += ((sizeof(n)-sizeof(i))/sizeof(i)); ! 1167: } ! 1168: i = 0; ! 1169: if (n < 0) { ! 1170: n = -n; ! 1171: *string++ = '-'; ! 1172: } ! 1173: ! 1174: do { ! 1175: n1 = n/b; ! 1176: dstack[i++] = (short) (n-(n1*b)); ! 1177: n = n1; ! 1178: } while (n != 0); /* figure number */ ! 1179: if ((b == 8) && ((i !=1 ) || (dstack[0] != 0))) dstack[i++]=0; ! 1180: while (i<width) dstack[i++] = 0; ! 1181: while (i > 0) *string++ =(dstack[--i] + '0'); /* print number */ ! 1182: } ! 1183: break; ! 1184: case 'P': ! 1185: width *= SREGION; ! 1186: /* Fall through */ ! 1187: case 'p': ! 1188: while (width > 0) { ! 1189: *string++ = *NOP; ! 1190: width -= ttywarp; ! 1191: } ! 1192: adx--; ! 1193: break; ! 1194: case 's': ! 1195: string = strcpy(string,(char *)*adx); ! 1196: break; ! 1197: case 'm': ! 1198: case 'M': ! 1199: { ! 1200: char *cp; ! 1201: if (c=='m') { ! 1202: cp = &TMAP[width * (*adx)]; ! 1203: } else { ! 1204: cp = &SMAP[width * (*adx)]; ! 1205: } ! 1206: for (c = 0; c < width; c++) { ! 1207: if (*cp) *string++ = *cp++; ! 1208: } ! 1209: } ! 1210: break; ! 1211: case 'c': ! 1212: c = *adx; ! 1213: if (c) { ! 1214: *string++ = c; ! 1215: } else { ! 1216: *string++ = '^'; ! 1217: *string++ = '@'; /* punt */ ! 1218: } ! 1219: break; ! 1220: case '%': ! 1221: *string++ ='%'; ! 1222: adx--; ! 1223: break; ! 1224: default: ! 1225: break; ! 1226: } ! 1227: adx++; ! 1228: goto loop; ! 1229: } ! 1230: ! 1231: mgetchar() ! 1232: { ! 1233: fflush(stdout); /* force output */ ! 1234: return(0177 & getchar()); ! 1235: } ! 1236: ! 1237: /*VARARGS1*/ ! 1238: ! 1239: eprintf(string,a1,a2,a3,a4,a5,a6,a7) ! 1240: ! 1241: register char *string; ! 1242: ! 1243: { ! 1244: char pbuf[1024]; ! 1245: seprintf(pbuf,string,a1,a2,a3,a4,a5,a6,a7); ! 1246: PUTS(pbuf); ! 1247: } ! 1248: ! 1249: ! 1250: ! 1251: xprintf(sp,ap1,ap2,ap3,ap4,ap5,ap6) ! 1252: register char *sp; ! 1253: { ! 1254: char sbuf[0400]; /* buffer */ ! 1255: register c; ! 1256: int x; ! 1257: ! 1258: ! 1259: sprintf(sbuf,sp,ap1,ap2,ap3,ap4,ap5,ap6); ! 1260: sp = sbuf; ! 1261: while (c = *sp++) { ! 1262: if (c == '\n') { ! 1263: clrl(); ! 1264: if (++mline >= ECHOL) { ! 1265: mline=0; ! 1266: } ! 1267: mcol=0; ! 1268: } else { ! 1269: xputc(c); ! 1270: } ! 1271: } ! 1272: } ! 1273: ! 1274: die(arg) ! 1275: int arg; ! 1276: { ! 1277: mgo(SCRNLIN-1,0); ! 1278: clrl(); ! 1279: cook(); ! 1280: if (arg) abort(arg); ! 1281: else exit(0); ! 1282: } ! 1283: ttystart() ! 1284: { ! 1285: int i; ! 1286: char *tp; ! 1287: ! 1288: setbuf(stdout,ttobuf); ! 1289: ! 1290: uncook(); ! 1291: for (i = 0; i < 16; i++) { ! 1292: signal(i,die); ! 1293: } ! 1294: tp = getenv("TERM"); ! 1295: if (tp == NULL) ttype(); ! 1296: else sttype(tp); ! 1297: } ! 1298: ! 1299: insrtc(c) ! 1300: int c; ! 1301: { ! 1302: if (INSERTC == NULL) return(0); ! 1303: INSON = 1; ! 1304: ldchar = c; ! 1305: ldcol = mcol-1; ! 1306: mputc(c); ! 1307: INSON = 0; ! 1308: return(1); ! 1309: } ! 1310: delc() ! 1311: { ! 1312: register i; ! 1313: ! 1314: if (DELC == NULL) return(0); ! 1315: SREGION=scrjnk[mline]-mcol; /* number of char's gobbled */ ! 1316: if (DELMODE && (osert == 0)) { ! 1317: eprintf(INSERTM); ! 1318: osert++; ! 1319: } ! 1320: eprintf(DELC); /*clobber next char */ ! 1321: for (i = mcol; i <=scrjnk[mline];i++) { ! 1322: cmap[mline] [i] = cmap[mline] [i+1]; ! 1323: } ! 1324: scrjnk[mline]--; ! 1325: return(1); ! 1326: } ! 1327: ! 1328: /* adjust vertical position of line -- open (or close) lines on */ ! 1329: /* the screen argument is the number of lines to add (or drop). */ ! 1330: ! 1331: vadjust(xline,tline,x) ! 1332: ! 1333: register x; ! 1334: int xline; ! 1335: int tline; ! 1336: { ! 1337: register i; ! 1338: register j; ! 1339: int oldx; ! 1340: ! 1341: if (LOPEN == NULL) return(0); ! 1342: ! 1343: oldx = xline; ! 1344: ! 1345: if (x<0) { ! 1346: x = -x; ! 1347: i = 1; ! 1348: } else i = 0; ! 1349: SREGION=tline-oldx; /* effected region */ ! 1350: if (i) { /* if deleting lines */ ! 1351: sgo(xline,0); ! 1352: ! 1353: if (SCREG) { /*if vt100 stype scrolling */ ! 1354: eprintf(SCREG,oldx+XBASE,tline+XBASE); /*define region*/ ! 1355: scrlin = scrcol = 0; ! 1356: sgo(tline,0); ! 1357: for (i = 0; i < x; i ++) { ! 1358: eprintf(SSCROLL); ! 1359: } ! 1360: eprintf(SCREG,XBASE,SCRNLIN); ! 1361: scrlin = scrcol = 0; ! 1362: } else { ! 1363: for (i = 0; i < x; i++) { ! 1364: eprintf(LDEL); ! 1365: } ! 1366: sgo(tline-x+1,0); ! 1367: for (i = 0; i < x; i++) { ! 1368: eprintf(LOPEN); ! 1369: } ! 1370: } ! 1371: sgo(oldx,0); ! 1372: vshift (oldx,tline,x); ! 1373: } else { ! 1374: if (SCREG) { /* if vt100 style scrolling */ ! 1375: ! 1376: eprintf(SCREG,oldx+XBASE,tline+XBASE); /*define region */ ! 1377: scrlin = scrcol = 0; /* vt100 dies */ ! 1378: sgo(xline,0); ! 1379: for (i = 0; i < x; i ++) { ! 1380: eprintf(RSCROLL); ! 1381: } ! 1382: eprintf(SCREG,XBASE,SCRNLIN); ! 1383: scrlin = scrcol = 0; ! 1384: } else { ! 1385: sgo(tline+1-x,0); ! 1386: for (i = 0; i < x;i++) eprintf(LDEL); ! 1387: sgo(oldx,0); ! 1388: for (i = 0; i < x; i++) eprintf(LOPEN); ! 1389: } ! 1390: mgo(oldx,0); ! 1391: ! 1392: vshift(oldx,tline,-x); ! 1393: } ! 1394: return(1); ! 1395: } ! 1396: ! 1397: ! 1398: /* sscroll -- try to fix display by scrolling */ ! 1399: ! 1400: sscroll(x) ! 1401: ! 1402: register int x; ! 1403: ! 1404: { ! 1405: register int i; ! 1406: ! 1407: ! 1408: if (SSCROLL == NULL) return(0); ! 1409: ! 1410: ! 1411: sgo(SCRNLIN-1,0); /* to bottom */ ! 1412: SREGION=SCRNLIN; /* number of lines effected */ ! 1413: for (i = 0; i < x; i++) { ! 1414: eprintf(SSCROLL); /* scroll screen */ ! 1415: } ! 1416: vshift (0,SCRNLIN-1,x); ! 1417: } ! 1418: ! 1419: /* vshift -- shift the display image from top to bottom (inclusive) by x */ ! 1420: ! 1421: ! 1422: vshift(top,bottom,x) ! 1423: ! 1424: int top; ! 1425: int bottom; ! 1426: int x; ! 1427: ! 1428: { ! 1429: register i; ! 1430: register j; ! 1431: char *cp1; ! 1432: char *cp2; ! 1433: int *jnkptr; ! 1434: int start; ! 1435: int stop; ! 1436: register int off; ! 1437: ! 1438: if (x > 0) { ! 1439: off = 1; ! 1440: start = top; ! 1441: stop = bottom+1; ! 1442: } else { ! 1443: off = -1; ! 1444: start = bottom; ! 1445: stop = top-1; ! 1446: } ! 1447: for (i = start,jnkptr = scrjnk+i; i != stop-x; i+=off,jnkptr+=off) { ! 1448: *jnkptr = *(jnkptr+x); ! 1449: cp1 = cmap[i]; ! 1450: cp2 = cmap[i+x]; ! 1451: for (j = 0; j < *jnkptr; j++) { ! 1452: *cp1++ = *cp2++; ! 1453: } ! 1454: } ! 1455: while (i != stop) { ! 1456: if (off > 0) { ! 1457: *jnkptr++ = 0; ! 1458: i++; ! 1459: } else { ! 1460: *jnkptr-- = 0; ! 1461: i--; ! 1462: } ! 1463: } ! 1464: } ! 1465: ! 1466: ! 1467: /* print an underscored character. */ ! 1468: ! 1469: pu(c) ! 1470: register char c; ! 1471: { ! 1472: register oc; ! 1473: c &= 0177; ! 1474: if ((c == 0)||(c == 040)) { ! 1475: /* bare underscore */ ! 1476: putchar('_'); ! 1477: return; /* just put out the underscore */ ! 1478: } ! 1479: if (UEND == 0) { ! 1480: eprintf(ULINE,c); ! 1481: } else { ! 1482: eprintf(ULINE); /* enter "underscore mode" */ ! 1483: putchar(c); ! 1484: eprintf(UEND); ! 1485: } ! 1486: } ! 1487: ! 1488: putit(c) ! 1489: char c; ! 1490: { ! 1491: if (drain) return; ! 1492: if (c & 0200) { ! 1493: pu(c); ! 1494: return; ! 1495: } ! 1496: putchar(0177 & c); ! 1497: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.