# 2.11BSD#431 - /usr/src/ucb/ex/ex_put.c

##### Functions

    draino            X
    fgoto             X
    flush             X
    flush1            X
    flush2            X
    flusho            X
    gTTY              X
    listchar          X
    lprintf           X
    noonl             X
    normal            X
    normchar          X
    normline          X
    noteinp           X
    numbline          X
    ostart            X
    ostop             X
    plod              X
    plodput           X
    pstart            X
    pstop             X
    putNFL            X
    putS              X
    putch             X
    putchar           X
    putnl             X
    putpad            X
    sTTY              X
    setoutt           X
    setty             X
    slobber           X
    tab               X
    termchar          X
    termreset         X
    tostart           X
    tostop            X
    ttcharoff         X
    vcook             X
    vraw              X

##### Variables

    linp              X
    obp               X
    t                 X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #if !defined(lint) && defined(DOSCCS)
       8: static char *sccsid = "@(#)ex_put.c	7.9.1 (2.11BSD GTE) 12/9/94";
       9: #endif
      10:
      11: #include "ex.h"
      12: #include "ex_tty.h"
      13: #include "ex_vis.h"
      14:
      15: /*
      16:  * Terminal driving and line formatting routines.
      17:  * Basic motion optimizations are done here as well
      18:  * as formatting of lines (printing of control characters,
      19:  * line numbering and the like).
      20:  */
      21:
      22: /*
      23:  * The routines outchar, putchar and pline are actually
      24:  * variables, and these variables point at the current definitions
      25:  * of the routines.  See the routine setflav.
      26:  * We sometimes make outchar be routines which catch the characters
      27:  * to be printed, e.g. if we want to see how long a line is.
      28:  * During open/visual, outchar and putchar will be set to
      29:  * routines in the file ex_vput.c (vputchar, vinschar, etc.).
      30:  */
      31: int (*Outchar)() = termchar;
      32: int (*Putchar)() = normchar;
      33: int (*Pline)() = normline;
      34:
      35: int (*
      36: setlist(t))()
      37:     bool t;
      38: {
      39:     register int (*P)();
      40:
      41:     listf = t;
      42:     P = Putchar;
      43:     Putchar = t ? listchar : normchar;
      44:     return (P);
      45: }
      46:
      47: int (*
      48: setnumb(t))()
      49:     bool t;
      50: {
      51:     register int (*P)();
      52:
      53:     numberf = t;
      54:     P = Pline;
      55:     Pline = t ? numbline : normline;
      56:     return (P);
      57: }
      58:
      59: /*
      60:  * Format c for list mode; leave things in common
      61:  * with normal print mode to be done by normchar.
      62:  */
      63: listchar(c)
      64:     register short c;
      65: {
      66:
      67:     c &= (TRIM|QUOTE);
      68:     switch (c) {
      69:
      70:     case '\t':
      71:     case '\b':
      72:         outchar('^');
      73:         c = ctlof(c);
      74:         break;
      75:
      76:     case '\n':
      77:         break;
      78:
      79:     case '\n' | QUOTE:
      80:         outchar('$');
      81:         break;
      82:
      83:     default:
      84:         if (c & QUOTE)
      85:             break;
      86:         if (c < ' ' && c != '\n' || c == DELETE)
      87:             outchar('^'), c = ctlof(c);
      88:         break;
      89:     }
      90:     normchar(c);
      91: }
      92:
      93: /*
      94:  * Format c for printing.
      95:  */
      96: normchar(c)
      97:     register short c;
      98: {
      99:     register char *colp;
     100:
     101:     c &= (TRIM|QUOTE);
     102:     if (c & QUOTE)
     103:         switch (c) {
     104:
     105:         case ' ' | QUOTE:
     106:         case '\b' | QUOTE:
     107:             break;
     108:
     109:         case QUOTE:
     110:             return;
     111:
     112:         default:
     113:             c &= TRIM;
     114:         }
     115:     else if (c < ' ' && (c != '\b' || !OS) && c != '\n' && c != '\t' || c == DELETE)
     116:         putchar('^'), c = ctlof(c);
     117:     outchar(c);
     118: }
     119:
     120: /*
     121:  * Print a line with a number.
     122:  */
     123: numbline(i)
     124:     int i;
     125: {
     126:
     127:     if (shudclob)
     128:         slobber(' ');
     129:     printf("%6d  ", i);
     130:     normline();
     131: }
     132:
     133: /*
     134:  * Normal line output, no numbering.
     135:  */
     136: normline()
     137: {
     138:     register char *cp;
     139:
     140:     if (shudclob)
     141:         slobber(linebuf[0]);
     142:     /* pdp-11 doprnt is not reentrant so can't use "printf" here
     143: 	   in case we are tracing */
     144:     for (cp = linebuf; *cp;)
     145:         putchar(*cp++);
     146:     if (!inopen)
     147:         putchar('\n' | QUOTE);
     148: }
     149:
     150: /*
     151:  * Given c at the beginning of a line, determine whether
     152:  * the printing of the line will erase or otherwise obliterate
     153:  * the prompt which was printed before.  If it won't, do it now.
     154:  */
     155: slobber(c)
     156:     int c;
     157: {
     158:
     159:     shudclob = 0;
     160:     switch (c) {
     161:
     162:     case '\t':
     163:         if (Putchar == listchar)
     164:             return;
     165:         break;
     166:
     167:     default:
     168:         return;
     169:
     170:     case ' ':
     171:     case 0:
     172:         break;
     173:     }
     174:     if (OS)
     175:         return;
     176:     flush();
     177:     putch(' ');
     178:     if (BC)
     179:         tputs(BC, 0, putch);
     180:     else
     181:         putch('\b');
     182: }
     183:
     184: /*
     185:  * The output buffer is initialized with a useful error
     186:  * message so we don't have to keep it in data space.
     187:  */
     188: static  char linb[66];
     189: char *linp = linb;
     190:
     191: /*
     192:  * Phadnl records when we have already had a complete line ending with \n.
     193:  * If another line starts without a flush, and the terminal suggests it,
     194:  * we switch into -nl mode so that we can send lineffeeds to avoid
     195:  * a lot of spacing.
     196:  */
     197: static  bool phadnl;
     198:
     199: /*
     200:  * Indirect to current definition of putchar.
     201:  */
     202: putchar(c)
     203:     int c;
     204: {
     205:
     206:     (*Putchar)(c);
     207: }
     208:
     209: /*
     210:  * Termchar routine for command mode.
     211:  * Watch for possible switching to -nl mode.
     212:  * Otherwise flush into next level of buffering when
     213:  * small buffer fills or at a newline.
     214:  */
     215: termchar(c)
     216:     int c;
     217: {
     218:
     219:     if (pfast == 0 && phadnl)
     220:         pstart();
     221:     if (c == '\n')
     222:         phadnl = 1;
     223:     else if (linp >= &linb[63])
     224:         flush1();
     225:     *linp++ = c;
     226:     if (linp >= &linb[63]) {
     227:         fgoto();
     228:         flush1();
     229:     }
     230: }
     231:
     232: flush()
     233: {
     234:
     235:     flush1();
     236:     flush2();
     237: }
     238:
     239: /*
     240:  * Flush from small line buffer into output buffer.
     241:  * Work here is destroying motion into positions, and then
     242:  * letting fgoto do the optimized motion.
     243:  */
     244: flush1()
     245: {
     246:     register char *lp;
     247:     register short c;
     248:
     249:     *linp = 0;
     250:     lp = linb;
     251:     while (*lp)
     252:         switch (c = *lp++) {
     253:
     254:         case '\r':
     255:             destline += destcol / COLUMNS;
     256:             destcol = 0;
     257:             continue;
     258:
     259:         case '\b':
     260:             if (destcol)
     261:                 destcol--;
     262:             continue;
     263:
     264:         case ' ':
     265:             destcol++;
     266:             continue;
     267:
     268:         case '\t':
     269:             destcol += value(TABSTOP) - destcol % value(TABSTOP);
     270:             continue;
     271:
     272:         case '\n':
     273:             destline += destcol / COLUMNS + 1;
     274:             if (destcol != 0 && destcol % COLUMNS == 0)
     275:                 destline--;
     276:             destcol = 0;
     277:             continue;
     278:
     279:         default:
     280:             fgoto();
     281:             for (;;) {
     282:                 if (AM == 0 && outcol == COLUMNS)
     283:                     fgoto();
     284:                 c &= TRIM;
     285:                 putch(c);
     286:                 if (c == '\b') {
     287:                     outcol--;
     288:                     destcol--;
     289:                 } else if (c >= ' ' && c != DELETE) {
     290:                     outcol++;
     291:                     destcol++;
     292:                     if (XN && outcol % COLUMNS == 0)
     293:                         putch('\r'), putch('\n');
     294:                 }
     295:                 c = *lp++;
     296:                 if (c <= ' ')
     297:                     break;
     298:             }
     299:             --lp;
     300:             continue;
     301:         }
     302:     linp = linb;
     303: }
     304:
     305: flush2()
     306: {
     307:
     308:     fgoto();
     309:     flusho();
     310:     pstop();
     311: }
     312:
     313: /*
     314:  * Sync the position of the output cursor.
     315:  * Most work here is rounding for terminal boundaries getting the
     316:  * column position implied by wraparound or the lack thereof and
     317:  * rolling up the screen to get destline on the screen.
     318:  */
     319: fgoto()
     320: {
     321:     register int l, c;
     322:
     323:     if (destcol > COLUMNS - 1) {
     324:         destline += destcol / COLUMNS;
     325:         destcol %= COLUMNS;
     326:     }
     327:     if (outcol > COLUMNS - 1) {
     328:         l = (outcol + 1) / COLUMNS;
     329:         outline += l;
     330:         outcol %= COLUMNS;
     331:         if (AM == 0) {
     332:             while (l > 0) {
     333:                 if (pfast)
     334:                     if (xCR)
     335:                         tputs(xCR, 0, putch);
     336:                     else
     337:                         putch('\r');
     338:                 if (xNL)
     339:                     tputs(xNL, 0, putch);
     340:                 else
     341:                     putch('\n');
     342:                 l--;
     343:             }
     344:             outcol = 0;
     345:         }
     346:         if (outline > LINES - 1) {
     347:             destline -= outline - (LINES - 1);
     348:             outline = LINES - 1;
     349:         }
     350:     }
     351:     if (destline > LINES - 1) {
     352:         l = destline;
     353:         destline = LINES - 1;
     354:         if (outline < LINES - 1) {
     355:             c = destcol;
     356:             if (pfast == 0 && (!CA || holdcm))
     357:                 destcol = 0;
     358:             fgoto();
     359:             destcol = c;
     360:         }
     361:         while (l > LINES - 1) {
     362:             /*
     363: 			 * The following linefeed (or simulation thereof)
     364: 			 * is supposed to scroll up the screen, since we
     365: 			 * are on the bottom line.  We make the assumption
     366: 			 * that linefeed will scroll.  If ns is in the
     367: 			 * capability list this won't work.  We should
     368: 			 * probably have an sc capability but sf will
     369: 			 * generally take the place if it works.
     370: 			 *
     371: 			 * Superbee glitch:  in the middle of the screen we
     372: 			 * have to use esc B (down) because linefeed screws up
     373: 			 * in "Efficient Paging" (what a joke) mode (which is
     374: 			 * essential in some SB's because CRLF mode puts garbage
     375: 			 * in at end of memory), but you must use linefeed to
     376: 			 * scroll since down arrow won't go past memory end.
     377: 			 * I turned this off after recieving Paul Eggert's
     378: 			 * Superbee description which wins better.
     379: 			 */
     380:             if (xNL /* && !XB */ && pfast)
     381:                 tputs(xNL, 0, putch);
     382:             else
     383:                 putch('\n');
     384:             l--;
     385:             if (pfast == 0)
     386:                 outcol = 0;
     387:         }
     388:     }
     389:     if (destline < outline && !(CA && !holdcm || UP != NOSTR))
     390:         destline = outline;
     391:     if (CA && !holdcm)
     392:         if (plod(costCM) > 0)
     393:             plod(0);
     394:         else
     395:             tputs(tgoto(CM, destcol, destline), 0, putch);
     396:     else
     397:         plod(0);
     398:     outline = destline;
     399:     outcol = destcol;
     400: }
     401:
     402: /*
     403:  * Tab to column col by flushing and then setting destcol.
     404:  * Used by "set all".
     405:  */
     406: tab(col)
     407:     int col;
     408: {
     409:
     410:     flush1();
     411:     destcol = col;
     412: }
     413:
     414: /*
     415:  * Move (slowly) to destination.
     416:  * Hard thing here is using home cursor on really deficient terminals.
     417:  * Otherwise just use cursor motions, hacking use of tabs and overtabbing
     418:  * and backspace.
     419:  */
     420:
     421: static int plodcnt, plodflg;
     422:
     423: plodput(c)
     424: {
     425:
     426:     if (plodflg)
     427:         plodcnt--;
     428:     else
     429:         putch(c);
     430: }
     431:
     432: plod(cnt)
     433: {
     434:     register int i, j, k;
     435:     register int soutcol, soutline;
     436:
     437:     plodcnt = plodflg = cnt;
     438:     soutcol = outcol;
     439:     soutline = outline;
     440:     /*
     441: 	 * Consider homing and moving down/right from there, vs moving
     442: 	 * directly with local motions to the right spot.
     443: 	 */
     444:     if (HO) {
     445:         /*
     446: 		 * i is the cost to home and tab/space to the right to
     447: 		 * get to the proper column.  This assumes ND space costs
     448: 		 * 1 char.  So i+destcol is cost of motion with home.
     449: 		 */
     450:         if (GT)
     451:             i = (destcol / value(HARDTABS)) + (destcol % value(HARDTABS));
     452:         else
     453:             i = destcol;
     454:         /*
     455: 		 * j is cost to move locally without homing
     456: 		 */
     457:         if (destcol >= outcol) {    /* if motion is to the right */
     458:             j = destcol / value(HARDTABS) - outcol / value(HARDTABS);
     459:             if (GT && j)
     460:                 j += destcol % value(HARDTABS);
     461:             else
     462:                 j = destcol - outcol;
     463:         } else
     464:             /* leftward motion only works if we can backspace. */
     465:             if (outcol - destcol <= i && (BS || BC))
     466:                 i = j = outcol - destcol; /* cheaper to backspace */
     467:             else
     468:                 j = i + 1; /* impossibly expensive */
     469:
     470:         /* k is the absolute value of vertical distance */
     471:         k = outline - destline;
     472:         if (k < 0)
     473:             k = -k;
     474:         j += k;
     475:
     476:         /*
     477: 		 * Decision.  We may not have a choice if no UP.
     478: 		 */
     479:         if (i + destline < j || (!UP && destline < outline)) {
     480:             /*
     481: 			 * Cheaper to home.  Do it now and pretend it's a
     482: 			 * regular local motion.
     483: 			 */
     484:             tputs(HO, 0, plodput);
     485:             outcol = outline = 0;
     486:         } else if (LL) {
     487:             /*
     488: 			 * Quickly consider homing down and moving from there.
     489: 			 * Assume cost of LL is 2.
     490: 			 */
     491:             k = (LINES - 1) - destline;
     492:             if (i + k + 2 < j && (k<=0 || UP)) {
     493:                 tputs(LL, 0, plodput);
     494:                 outcol = 0;
     495:                 outline = LINES - 1;
     496:             }
     497:         }
     498:     } else
     499:     /*
     500: 	 * No home and no up means it's impossible, so we return an
     501: 	 * incredibly big number to make cursor motion win out.
     502: 	 */
     503:         if (!UP && destline < outline)
     504:             return (500);
     505:     if (GT)
     506:         i = destcol % value(HARDTABS)
     507:             + destcol / value(HARDTABS);
     508:     else
     509:         i = destcol;
     510: /*
     511: 	if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) {
     512: 		j *= (k = strlen(BT));
     513: 		if ((k += (destcol&7)) > 4)
     514: 			j += 8 - (destcol&7);
     515: 		else
     516: 			j += k;
     517: 	} else
     518: */
     519:         j = outcol - destcol;
     520:     /*
     521: 	 * If we will later need a \n which will turn into a \r\n by
     522: 	 * the system or the terminal, then don't bother to try to \r.
     523: 	 */
     524:     if ((NONL || !pfast) && outline < destline)
     525:         goto dontcr;
     526:     /*
     527: 	 * If the terminal will do a \r\n and there isn't room for it,
     528: 	 * then we can't afford a \r.
     529: 	 */
     530:     if (NC && outline >= destline)
     531:         goto dontcr;
     532:     /*
     533: 	 * If it will be cheaper, or if we can't back up, then send
     534: 	 * a return preliminarily.
     535: 	 */
     536:     if (j > i + 1 || outcol > destcol && !BS && !BC) {
     537:         /*
     538: 		 * BUG: this doesn't take the (possibly long) length
     539: 		 * of xCR into account.
     540: 		 */
     541:         if (xCR)
     542:             tputs(xCR, 0, plodput);
     543:         else
     544:             plodput('\r');
     545:         if (NC) {
     546:             if (xNL)
     547:                 tputs(xNL, 0, plodput);
     548:             else
     549:                 plodput('\n');
     550:             outline++;
     551:         }
     552:         outcol = 0;
     553:     }
     554: dontcr:
     555:     /* Move down, if necessary, until we are at the desired line */
     556:     while (outline < destline) {
     557:         j = destline - outline;
     558:         if (j > costDP && DOWN_PARM) {
     559:             /* Win big on Tek 4025 */
     560:             tputs(tgoto(DOWN_PARM, 0, j), j, plodput);
     561:             outline += j;
     562:         }
     563:         else {
     564:             outline++;
     565:             if (xNL && pfast)
     566:                 tputs(xNL, 0, plodput);
     567:             else
     568:                 plodput('\n');
     569:         }
     570:         if (plodcnt < 0)
     571:             goto out;
     572:         if (NONL || pfast == 0)
     573:             outcol = 0;
     574:     }
     575:     if (BT)
     576:         k = strlen(BT); /* should probably be cost(BT) and moved out */
     577:     /* Move left, if necessary, to desired column */
     578:     while (outcol > destcol) {
     579:         if (plodcnt < 0)
     580:             goto out;
     581:         if (BT && !insmode && outcol - destcol > 4+k) {
     582:             tputs(BT, 0, plodput);
     583:             outcol--;
     584:             outcol -= outcol % value(HARDTABS); /* outcol &= ~7; */
     585:             continue;
     586:         }
     587:         j = outcol - destcol;
     588:         if (j > costLP && LEFT_PARM) {
     589:             tputs(tgoto(LEFT_PARM, 0, j), j, plodput);
     590:             outcol -= j;
     591:         }
     592:         else {
     593:             outcol--;
     594:             if (BC)
     595:                 tputs(BC, 0, plodput);
     596:             else
     597:                 plodput('\b');
     598:         }
     599:     }
     600:     /* Move up, if necessary, to desired row */
     601:     while (outline > destline) {
     602:         j = outline - destline;
     603:         if (UP_PARM && j > 1) {
     604:             /* Win big on Tek 4025 */
     605:             tputs(tgoto(UP_PARM, 0, j), j, plodput);
     606:             outline -= j;
     607:         }
     608:         else {
     609:             outline--;
     610:             tputs(UP, 0, plodput);
     611:         }
     612:         if (plodcnt < 0)
     613:             goto out;
     614:     }
     615:     /*
     616: 	 * Now move to the right, if necessary.  We first tab to
     617: 	 * as close as we can get.
     618: 	 */
     619:     if (GT && !insmode && destcol - outcol > 1) {
     620:         /* tab to right as far as possible without passing col */
     621:         for (;;) {
     622:             i = tabcol(outcol, value(HARDTABS));
     623:             if (i > destcol)
     624:                 break;
     625:             if (TA)
     626:                 tputs(TA, 0, plodput);
     627:             else
     628:                 plodput('\t');
     629:             outcol = i;
     630:         }
     631:         /* consider another tab and then some backspaces */
     632:         if (destcol - outcol > 4 && i < COLUMNS && (BC || BS)) {
     633:             if (TA)
     634:                 tputs(TA, 0, plodput);
     635:             else
     636:                 plodput('\t');
     637:             outcol = i;
     638:             /*
     639: 			 * Back up.  Don't worry about LEFT_PARM because
     640: 			 * it's never more than 4 spaces anyway.
     641: 			 */
     642:             while (outcol > destcol) {
     643:                 outcol--;
     644:                 if (BC)
     645:                     tputs(BC, 0, plodput);
     646:                 else
     647:                     plodput('\b');
     648:             }
     649:         }
     650:     }
     651:     /*
     652: 	 * We've tabbed as much as possible.  If we still need to go
     653: 	 * further (not exact or can't tab) space over.  This is a
     654: 	 * very common case when moving to the right with space.
     655: 	 */
     656:     while (outcol < destcol) {
     657:         j = destcol - outcol;
     658:         if (j > costRP && RIGHT_PARM) {
     659:             /*
     660: 			 * This probably happens rarely, if at all.
     661: 			 * It seems mainly useful for ANSI terminals
     662: 			 * with no hardware tabs, and I don't know
     663: 			 * of any such terminal at the moment.
     664: 			 */
     665:             tputs(tgoto(RIGHT_PARM, 0, j), j, plodput);
     666:             outcol += j;
     667:         }
     668:         else {
     669:             /*
     670: 			 * move one char to the right.  We don't use ND space
     671: 			 * because it's better to just print the char we are
     672: 			 * moving over.  There are various exceptions, however.
     673: 			 * If !inopen, vtube contains garbage.  If the char is
     674: 			 * a null or a tab we want to print a space.  Other
     675: 			 * random chars we use space for instead, too.
     676: 			 */
     677:             if (!inopen || vtube[outline]==NULL ||
     678:                 (i=vtube[outline][outcol]) < ' ')
     679:                 i = ' ';
     680:             if(i & QUOTE)   /* mjm: no sign extension on 3B */
     681:                 i = ' ';
     682:             if (insmode && ND)
     683:                 tputs(ND, 0, plodput);
     684:             else
     685:                 plodput(i);
     686:             outcol++;
     687:         }
     688:         if (plodcnt < 0)
     689:             goto out;
     690:     }
     691: out:
     692:     if (plodflg) {
     693:         outcol = soutcol;
     694:         outline = soutline;
     695:     }
     696:     return(plodcnt);
     697: }
     698:
     699: /*
     700:  * An input line arrived.
     701:  * Calculate new (approximate) screen line position.
     702:  * Approximate because kill character echoes newline with
     703:  * no feedback and also because of long input lines.
     704:  */
     705: noteinp()
     706: {
     707:
     708:     outline++;
     709:     if (outline > LINES - 1)
     710:         outline = LINES - 1;
     711:     destline = outline;
     712:     destcol = outcol = 0;
     713: }
     714:
     715: /*
     716:  * Something weird just happened and we
     717:  * lost track of whats happening out there.
     718:  * Since we cant, in general, read where we are
     719:  * we just reset to some known state.
     720:  * On cursor addressible terminals setting to unknown
     721:  * will force a cursor address soon.
     722:  */
     723: termreset()
     724: {
     725:
     726:     endim();
     727:     if (TI) /* otherwise it flushes anyway, and 'set tty=dumb' vomits */
     728:         putpad(TI);  /*adb change -- emit terminal initial sequence */
     729:     destcol = 0;
     730:     destline = LINES - 1;
     731:     if (CA) {
     732:         outcol = UKCOL;
     733:         outline = UKCOL;
     734:     } else {
     735:         outcol = destcol;
     736:         outline = destline;
     737:     }
     738: }
     739:
     740: /*
     741:  * Low level buffering, with the ability to drain
     742:  * buffered output without printing it.
     743:  */
     744: char    *obp = obuf;
     745:
     746: draino()
     747: {
     748:
     749:     obp = obuf;
     750: }
     751:
     752: flusho()
     753: {
     754:
     755:     if (obp != obuf) {
     756:         write(1, obuf, obp - obuf);
     757:         obp = obuf;
     758:     }
     759: }
     760:
     761: putnl()
     762: {
     763:
     764:     putchar('\n');
     765: }
     766:
     767: putS(cp)
     768:     char *cp;
     769: {
     770:
     771:     if (cp == NULL)
     772:         return;
     773:     while (*cp)
     774:         putch(*cp++);
     775: }
     776:
     777:
     778: putch(c)
     779:     int c;
     780: {
     781:
     782: #ifdef OLD3BTTY     /* mjm */
     783:     if(c == '\n')   /* mjm: Fake "\n\r" for '\n' til fix in 3B firmware */
     784:         putch('\r');    /* mjm: vi does "stty -icanon" => -onlcr !! */
     785: #endif
     786:     *obp++ = c & 0177;
     787:     if (obp >= &obuf[sizeof obuf])
     788:         flusho();
     789: }
     790:
     791: /*
     792:  * Miscellaneous routines related to output.
     793:  */
     794:
     795: /*
     796:  * Put with padding
     797:  */
     798: putpad(cp)
     799:     char *cp;
     800: {
     801:
     802:     flush();
     803:     tputs(cp, 0, putch);
     804: }
     805:
     806: /*
     807:  * Set output through normal command mode routine.
     808:  */
     809: setoutt()
     810: {
     811:
     812:     Outchar = termchar;
     813: }
     814:
     815: /*
     816:  * Printf (temporarily) in list mode.
     817:  */
     818: /*VARARGS2*/
     819: lprintf(cp, dp)
     820:     char *cp, *dp;
     821: {
     822:     register int (*P)();
     823:
     824:     P = setlist(1);
     825:     printf(cp, dp);
     826:     Putchar = P;
     827: }
     828:
     829: /*
     830:  * Newline + flush.
     831:  */
     832: putNFL()
     833: {
     834:
     835:     putnl();
     836:     flush();
     837: }
     838:
     839: /*
     840:  * Try to start -nl mode.
     841:  */
     842: pstart()
     843: {
     844:
     845:     if (NONL)
     846:         return;
     847:     if (!value(OPTIMIZE))
     848:         return;
     849:     if (ruptible == 0 || pfast)
     850:         return;
     851:     fgoto();
     852:     flusho();
     853:     pfast = 1;
     854:     normtty++;
     855: #ifndef USG3TTY
     856:     tty.sg_flags = normf & ~(ECHO|XTABS|CRMOD);
     857: #else
     858:     tty = normf;
     859:     tty.c_oflag &= ~(ONLCR|TAB3);
     860:     tty.c_lflag &= ~ECHO;
     861: #endif
     862:     sTTY(1);
     863: }
     864:
     865: /*
     866:  * Stop -nl mode.
     867:  */
     868: pstop()
     869: {
     870:
     871:     if (inopen)
     872:         return;
     873:     phadnl = 0;
     874:     linp = linb;
     875:     draino();
     876:     normal(normf);
     877:     pfast &= ~1;
     878: }
     879:
     880: /*
     881:  * Prep tty for open mode.
     882:  */
     883: ttymode
     884: ostart()
     885: {
     886:     ttymode f;
     887:
     888:     if (!intty)
     889:         error("Open and visual must be used interactively");
     890:     gTTY(1);
     891:     normtty++;
     892: #ifndef USG3TTY
     893:     f = tty.sg_flags;
     894:     tty.sg_flags = (normf &~ (ECHO|XTABS|CRMOD)) |
     895: # ifdef CBREAK
     896:                             CBREAK;
     897: # else
     898:                             RAW;
     899: # endif
     900: # ifdef TIOCGETC
     901:     ttcharoff();
     902: # endif
     903: #else
     904:     f = tty;
     905:     tty = normf;
     906:     tty.c_iflag &= ~ICRNL;
     907:     tty.c_lflag &= ~(ECHO|ICANON);
     908:     tty.c_oflag &= ~(TAB3|ONLCR);
     909:     tty.c_cc[VMIN] = 1;
     910:     tty.c_cc[VTIME] = 1;
     911:     ttcharoff();
     912: #endif
     913:     sTTY(1);
     914:     tostart();
     915:     pfast |= 2;
     916:     return (f);
     917: }
     918:
     919: /* actions associated with putting the terminal in open mode */
     920: tostart()
     921: {
     922:     putpad(VS);
     923:     putpad(KS);
     924:     if (!value(MESG)) {
     925:         if (ttynbuf[0] == 0) {
     926:             register char *tn;
     927:             if ((tn=ttyname(2)) == NULL &&
     928:                 (tn=ttyname(1)) == NULL &&
     929:                 (tn=ttyname(0)) == NULL)
     930:                 ttynbuf[0] = 1;
     931:             else
     932:                 strcpy(ttynbuf, tn);
     933:         }
     934:         if (ttynbuf[0] != 1) {
     935:             struct stat sbuf;
     936:             stat(ttynbuf, &sbuf);
     937:             ttymesg = sbuf.st_mode & 0777;
     938:             chmod(ttynbuf,
     939: #ifdef UCBV7
     940:     /*
     941: 	 * This applies to the UCB V7 Pdp-11 system with the
     942: 	 * -u write option only.
     943: 	 */
     944:                     0611    /* 11 = urgent only allowed */
     945: #else
     946:                     0600
     947: #endif
     948:                         );
     949:         }
     950:     }
     951: }
     952:
     953: /*
     954:  * Turn off start/stop chars if they aren't the default ^S/^Q.
     955:  * This is so idiots who make esc their start/stop don't lose.
     956:  * We always turn off quit since datamedias send ^\ for their
     957:  * right arrow key.
     958:  */
     959: #ifdef TIOCGETC
     960: ttcharoff()
     961: {
     962:     nttyc.t_quitc = '\377';
     963:     if (nttyc.t_startc != CTRL(q))
     964:         nttyc.t_startc = '\377';
     965:     if (nttyc.t_stopc != CTRL(s))
     966:         nttyc.t_stopc = '\377';
     967: # ifdef TIOCLGET
     968:     nlttyc.t_suspc = '\377';    /* ^Z */
     969:     nlttyc.t_dsuspc = '\377';   /* ^Y */
     970:     nlttyc.t_flushc = '\377';   /* ^O */
     971:     nlttyc.t_lnextc = '\377';   /* ^V */
     972: # endif
     973: }
     974: #endif
     975:
     976: #ifdef USG3TTY
     977: ttcharoff()
     978: {
     979:     tty.c_cc[VQUIT] = '\377';
     980: # ifdef VSTART
     981:     /*
     982: 	 * The following is sample code if USG ever lets people change
     983: 	 * their start/stop chars.  As long as they can't we can't get
     984: 	 * into trouble so we just leave them alone.
     985: 	 */
     986:     if (tty.c_cc[VSTART] != CTRL(q))
     987:         tty.c_cc[VSTART] = '\377';
     988:     if (tty.c_cc[VSTOP] != CTRL(s))
     989:         tty.c_cc[VSTOP] = '\377';
     990: # endif
     991: }
     992: #endif
     993:
     994: /*
     995:  * Stop open, restoring tty modes.
     996:  */
     997: ostop(f)
     998:     ttymode f;
     999: {
    1000:
    1001: #ifndef USG3TTY
    1002:     pfast = (f & CRMOD) == 0;
    1003: #else
    1004:     pfast = (f.c_oflag & ONLCR) == 0;
    1005: #endif
    1006:     termreset(), fgoto(), flusho();
    1007:     normal(f);
    1008:     tostop();
    1009: }
    1010:
    1011: /* Actions associated with putting the terminal in the right mode. */
    1012: tostop()
    1013: {
    1014:     putpad(VE);
    1015:     putpad(KE);
    1016:     if (!value(MESG) && ttynbuf[0]>1)
    1017:         chmod(ttynbuf, ttymesg);
    1018: }
    1019:
    1020: #ifndef CBREAK
    1021: /*
    1022:  * Into cooked mode for interruptibility.
    1023:  */
    1024: vcook()
    1025: {
    1026:
    1027:     tty.sg_flags &= ~RAW;
    1028:     sTTY(1);
    1029: }
    1030:
    1031: /*
    1032:  * Back into raw mode.
    1033:  */
    1034: vraw()
    1035: {
    1036:
    1037:     tty.sg_flags |= RAW;
    1038:     sTTY(1);
    1039: }
    1040: #endif
    1041:
    1042: /*
    1043:  * Restore flags to normal state f.
    1044:  */
    1045: normal(f)
    1046:     ttymode f;
    1047: {
    1048:
    1049:     if (normtty > 0) {
    1050:         setty(f);
    1051:         normtty--;
    1052:     }
    1053: }
    1054:
    1055: /*
    1056:  * Straight set of flags to state f.
    1057:  */
    1058: ttymode
    1059: setty(f)
    1060:     ttymode f;
    1061: {
    1062: #ifndef USG3TTY
    1063:     register int ot = tty.sg_flags;
    1064: #else
    1065:     ttymode ot;
    1066:     ot = tty;
    1067: #endif
    1068:
    1069: #ifndef USG3TTY
    1070:     if (f == normf) {
    1071:         nttyc = ottyc;
    1072: # ifdef TIOCLGET
    1073:         nlttyc = olttyc;
    1074: # endif
    1075:     } else
    1076:         ttcharoff();
    1077:     tty.sg_flags = f;
    1078: #else
    1079:     if (tty.c_lflag & ICANON)
    1080:         ttcharoff();
    1081:     tty = f;
    1082: #endif
    1083:     sTTY(1);
    1084:     return (ot);
    1085: }
    1086:
    1087: gTTY(i)
    1088:     int i;
    1089: {
    1090:
    1091: #ifndef USG3TTY
    1092:     ignore(gtty(i, &tty));
    1093: # ifdef TIOCGETC
    1094:     ioctl(i, TIOCGETC, &ottyc);
    1095:     nttyc = ottyc;
    1096: # endif
    1097: # ifdef TIOCGLTC
    1098:     ioctl(i, TIOCGLTC, &olttyc);
    1099:     nlttyc = olttyc;
    1100: # endif
    1101: #else
    1102:     ioctl(i, TCGETA, &tty);
    1103: #endif
    1104: }
    1105:
    1106: /*
    1107:  * sTTY: set the tty modes on file descriptor i to be what's
    1108:  * currently in global "tty".  (Also use nttyc if needed.)
    1109:  */
    1110: sTTY(i)
    1111:     int i;
    1112: {
    1113:
    1114: #ifndef USG3TTY
    1115: # ifdef USG
    1116:     /* Bug in USG tty driver, put out a DEL as a patch. */
    1117:     if (tty.sg_ospeed >= B1200)
    1118:         write(1, "\377", 1);
    1119: # endif
    1120:
    1121: # ifdef TIOCSETN
    1122:     /* Don't flush typeahead if we don't have to */
    1123:     ioctl(i, TIOCSETN, &tty);
    1124: # else
    1125:     /* We have to.  Too bad. */
    1126:     stty(i, &tty);
    1127: # endif
    1128:
    1129: # ifdef TIOCGETC
    1130:     /* Update the other random chars while we're at it. */
    1131:     ioctl(i, TIOCSETC, &nttyc);
    1132: # endif
    1133: # ifdef TIOCSLTC
    1134:     ioctl(i, TIOCSLTC, &nlttyc);
    1135: # endif
    1136:
    1137: #else
    1138:     /* USG 3 very simple: just set everything */
    1139:     ioctl(i, TCSETAW, &tty);
    1140: #endif
    1141: }
    1142:
    1143: /*
    1144:  * Print newline, or blank if in open/visual
    1145:  */
    1146: noonl()
    1147: {
    1148:
    1149:     putchar(Outchar != termchar ? ' ' : '\n');
    1150: }

#### Defined functions

draino defined in line 746; used 4 times

- in line 875
- in /usr/src/ucb/ex/ex.c line 140
- in /usr/src/ucb/ex/ex_subr.c line 827
- in /usr/src/ucb/ex/ex_v.c line 397

fgoto defined in line 319; used 11 times

- in line 227, 280-283(2), 308, 358, 851, 1006
- in /usr/src/ucb/ex/ex_vadj.c line 421, 428
- in /usr/src/ucb/ex/ex_vput.c line 316, 353

flush defined in line 232; used 29 times

- in line 176, 802, 836
- in /usr/src/ucb/ex/ex_cmds.c line 78, 472, 572, 831
- in /usr/src/ucb/ex/ex_cmds2.c line 133, 200, 503, 556
- in /usr/src/ucb/ex/ex_get.c line 97, 141, 193
- in /usr/src/ucb/ex/ex_io.c line 107, 405, 848
- in /usr/src/ucb/ex/ex_re.c line 384, 390, 533
- in /usr/src/ucb/ex/ex_set.c line 153, 210
- in /usr/src/ucb/ex/ex_subr.c line 909
- in /usr/src/ucb/ex/ex_temp.c line 88
- in /usr/src/ucb/ex/ex_unix.c line 103, 123, 227
- in /usr/src/ucb/ex/ex_vops2.c line 823
- in /usr/src/ucb/ex/ex_vops3.c line 376

flush1 defined in line 244; used 7 times

- in line 224-228(2), 235, 410
- in /usr/src/ucb/ex/ex_cmds.c line 450, 789
- in /usr/src/ucb/ex/ex_cmdsub.c line 836

flush2 defined in line 305; used 1 times

- in line 236

flusho defined in line 752; used 12 times

- in line 309, 788, 852, 1006
- in /usr/src/ucb/ex/ex_v.c line 170
- in /usr/src/ucb/ex/ex_vget.c line 109
- in /usr/src/ucb/ex/ex_vops.c line 751
- in /usr/src/ucb/ex/ex_vops2.c line 442
- in /usr/src/ucb/ex/ex_vput.c line 170
- in /usr/src/ucb/ex/ex_vwind.c line 283, 383, 419

gTTY defined in line 1087; used 2 times

- in line 890
- in /usr/src/ucb/ex/ex.c line 105

listchar defined in line 63; used 3 times

- in line 43, 163
- in /usr/src/ucb/ex/ex.h line 367

lprintf defined in line 819; used 9 times

- in /usr/src/ucb/ex/ex_cmdsub.c line 97, 1098-1102(3)
- in /usr/src/ucb/ex/ex_io.c line 98, 539
- in /usr/src/ucb/ex/ex_subr.c line 151, 625
- in /usr/src/ucb/ex/ex_unix.c line 117

noonl defined in line 1146; used 11 times

- in /usr/src/ucb/ex/ex_cmds.c line 294, 676, 817
- in /usr/src/ucb/ex/ex_cmds2.c line 179
- in /usr/src/ucb/ex/ex_cmdsub.c line 102
- in /usr/src/ucb/ex/ex_io.c line 329, 847
- in /usr/src/ucb/ex/ex_re.c line 532
- in /usr/src/ucb/ex/ex_set.c line 82, 209
- in /usr/src/ucb/ex/ex_unix.c line 102

normal defined in line 1045; used 2 times

- in line 876, 1007

normchar defined in line 96; used 4 times

- in line 32, 43, 90
- in /usr/src/ucb/ex/ex.h line 369

normline defined in line 136; used 4 times

- in line 33, 55, 130
- in /usr/src/ucb/ex/ex.h line 370

noteinp defined in line 705; used 3 times

- in /usr/src/ucb/ex/ex_get.c line 105, 182
- in /usr/src/ucb/ex/ex_re.c line 395

numbline defined in line 123; used 4 times

- in line 55
- in /usr/src/ucb/ex/ex.h line 371
- in /usr/src/ucb/ex/ex_get.c line 132-134(2)

ostart defined in line 883; used 4 times

- in /usr/src/ucb/ex/ex_tty.h line 160
- in /usr/src/ucb/ex/ex_v.c line 124, 232
- in /usr/src/ucb/ex/ex_vmain.c line 1245

ostop defined in line 997; used 3 times

- in /usr/src/ucb/ex/ex_cmds2.c line 144
- in /usr/src/ucb/ex/ex_v.c line 165
- in /usr/src/ucb/ex/ex_vmain.c line 1234

plod defined in line 432; used 3 times

- in line 392-397(3)

plodput defined in line 423; used 24 times

- in line 484, 493, 542-549(4), 560, 566-568(2), 582, 589, 595-597(2), 605-610(2), 626-628(2), 634-636(2), 645-647(2), 665, 683-685(2)

pstart defined in line 842; used 2 times

- in line 220
- in /usr/src/ucb/ex/ex_cmdsub.c line 840

pstop defined in line 868; used 3 times

- in line 310
- in /usr/src/ucb/ex/ex.c line 147
- in /usr/src/ucb/ex/ex_subr.c line 829

putNFL defined in line 832; used 9 times

- in /usr/src/ucb/ex/ex_cmds2.c line 106, 184
- in /usr/src/ucb/ex/ex_cmdsub.c line 1103
- in /usr/src/ucb/ex/ex_set.c line 178
- in /usr/src/ucb/ex/ex_subr.c line 261, 451
- in /usr/src/ucb/ex/ex_temp.c line 53
- in /usr/src/ucb/ex/ex_v.c line 190
- in /usr/src/ucb/ex/ex_vmain.c line 1242

putS defined in line 767; never used
putch defined in line 778; used 24 times

- in line 177-181(3), 285, 293(2), 335-341(4), 381-383(2), 395, 429, 774, 784, 803
- in /usr/src/ucb/ex/ex.h line 376
- in /usr/src/ucb/ex/ex_cmds2.c line 496-497(2), 519
- in /usr/src/ucb/ex/ex_subr.c line 127
- in /usr/src/ucb/ex/ex_vadj.c line 759
- in /usr/src/ucb/ex/ex_vis.h line 260

putchar defined in line 202; used 7 times

- in /usr/src/ucb/ex/printf.c line 54, 184-185(2), 333, 342-351(3)

putnl defined in line 761; used 8 times

- in line 835
- in /usr/src/ucb/ex/ex_cmds.c line 870-874(2)
- in /usr/src/ucb/ex/ex_cmds2.c line 149
- in /usr/src/ucb/ex/ex_cmdsub.c line 858
- in /usr/src/ucb/ex/ex_subr.c line 362
- in /usr/src/ucb/ex/ex_unix.c line 122
- in /usr/src/ucb/ex/ex_vmain.c line 1241

putpad defined in line 798; used 16 times

- in line 728, 922-923(2), 1014-1015(2)
- in /usr/src/ucb/ex/ex_cmds.c line 571, 830
- in /usr/src/ucb/ex/ex_cmds2.c line 526
- in /usr/src/ucb/ex/ex_subr.c line 125, 366-369(2), 624-627(2), 908
- in /usr/src/ucb/ex/ex_temp.c line 87
- in /usr/src/ucb/ex/ex_tty.c line 70

sTTY defined in line 1110; used 5 times

- in line 862, 913, 1028, 1038, 1083

setoutt defined in line 809; used 5 times

- in /usr/src/ucb/ex/ex_cmds2.c line 132, 390
- in /usr/src/ucb/ex/ex_cmdsub.c line 884
- in /usr/src/ucb/ex/ex_v.c line 166
- in /usr/src/ucb/ex/ex_vmain.c line 1235

setty defined in line 1058; used 9 times

- in line 1050
- in /usr/src/ucb/ex/ex_cmds.c line 473
- in /usr/src/ucb/ex/ex_subr.c line 906, 919
- in /usr/src/ucb/ex/ex_tty.h line 160
- in /usr/src/ucb/ex/ex_unix.c line 147-151(2), 223
- in /usr/src/ucb/ex/ex_v.c line 428

slobber defined in line 155; used 2 times

- in line 128, 141

tab defined in line 406; used 5 times

- in /usr/src/ucb/ex/ex_get.c line 150, 157, 172
- in /usr/src/ucb/ex/ex_set.c line 172-175(2)

termchar defined in line 215; used 4 times

- in line 31, 812, 1149
- in /usr/src/ucb/ex/ex.h line 378

termreset defined in line 723; used 5 times

- in line 1006
- in /usr/src/ucb/ex/ex_cmds2.c line 492
- in /usr/src/ucb/ex/ex_tty.c line 137
- in /usr/src/ucb/ex/ex_unix.c line 228
- in /usr/src/ucb/ex/ex_vmain.c line 1243

tostart defined in line 920; used 2 times

- in line 914
- in /usr/src/ucb/ex/ex_cmds2.c line 527

tostop defined in line 1012; used 3 times

- in line 1008
- in /usr/src/ucb/ex/ex_cmds.c line 470
- in /usr/src/ucb/ex/ex_cmds2.c line 550

ttcharoff defined in line 977; used 4 times

- in line 901, 911, 1076-1080(2)

vcook defined in line 1024; used 5 times

- in /usr/src/ucb/ex/ex_vmain.c line 941
- in /usr/src/ucb/ex/ex_voper.c line 631
- in /usr/src/ucb/ex/ex_vwind.c line 268, 370, 402

vraw defined in line 1034; used 9 times

- in /usr/src/ucb/ex/ex_cmds2.c line 506
- in /usr/src/ucb/ex/ex_subr.c line 835
- in /usr/src/ucb/ex/ex_vmain.c line 947-951(2)
- in /usr/src/ucb/ex/ex_voper.c line 635-639(2)
- in /usr/src/ucb/ex/ex_vwind.c line 283, 383, 419

#### Defined variables

linb defined in line 188; used 6 times

- in line 189, 223-226(2), 250, 302, 874

linp defined in line 189; used 6 times

- in line 223-226(3), 249, 302, 874

obp defined in line 744; used 6 times

- in line 749, 755-757(3), 786-787(2)

phadnl defined in line 197; used 3 times

- in line 219-222(2), 873

plodcnt defined in line 421; used 7 times

- in line 427, 437, 570, 579, 612, 688, 696

plodflg defined in line 421; used 3 times

- in line 426, 437, 692

sccsid defined in line 8; never used
t defined in line 49; used 6 times

- in line 36-55(6)

Last modified: 1994-12-10 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3162 |