1: /* Copyright (c) 1979 Regents of the University of California */
   2: #define CTRL(c) ('c' & 037)
   3: 
   4: char    *UP;
   5: char    *BC;
   6: 
   7: /*
   8:  * Routine to perform cursor addressing.
   9:  * CM is a string containing printf type escapes to allow
  10:  * cursor addressing.  We start out ready to print the destination
  11:  * line, and switch each time we print row or column.
  12:  * The following escapes are defined for substituting row/column:
  13:  *
  14:  *	%d	as in printf
  15:  *	%2	like %2d
  16:  *	%3	like %3d
  17:  *	%.	gives %c hacking special case characters
  18:  *	%+x	like %c but adding x first
  19:  *
  20:  *	The codes below affect the state but don't use up a value.
  21:  *
  22:  *	%>xy	if value > x add y
  23:  *	%r	reverses row/column
  24:  *	%i	increments row/column (for one origin indexing)
  25:  *	%%	gives %
  26:  *	%B	BCD (2 decimal digits encoded in one byte)
  27:  *	%D	Delta Data (backwards bcd)
  28:  *
  29:  * all other characters are ``self-inserting''.
  30:  */
  31: char *
  32: tgoto(CM, destcol, destline)
  33:     char *CM;
  34:     int destcol, destline;
  35: {
  36:     static char result[64];
  37:     static char added[10];
  38:     char *cp = CM;
  39:     register char *dp = result;
  40:     register int c;
  41:     int oncol = 0;
  42:     register int which = destline;
  43: 
  44:     if (cp == 0) {
  45: toohard:
  46:         /*
  47: 		 * ``We don't do that under BOZO's big top''
  48: 		 */
  49:         return ("OOPS");
  50:     }
  51:     added[0] = 0;
  52:     while (c = *cp++) {
  53:         if (c != '%') {
  54:             *dp++ = c;
  55:             continue;
  56:         }
  57:         switch (c = *cp++) {
  58: 
  59: #ifdef CM_N
  60:         case 'n':
  61:             destcol ^= 0140;
  62:             destline ^= 0140;
  63:             goto setwhich;
  64: #endif
  65: 
  66:         case 'd':
  67:             if (which < 10)
  68:                 goto one;
  69:             if (which < 100)
  70:                 goto two;
  71:             /* fall into... */
  72: 
  73:         case '3':
  74:             *dp++ = (which / 100) | '0';
  75:             which %= 100;
  76:             /* fall into... */
  77: 
  78:         case '2':
  79: two:
  80:             *dp++ = which / 10 | '0';
  81: one:
  82:             *dp++ = which % 10 | '0';
  83: swap:
  84:             oncol = 1 - oncol;
  85: setwhich:
  86:             which = oncol ? destcol : destline;
  87:             continue;
  88: 
  89: #ifdef CM_GT
  90:         case '>':
  91:             if (which > *cp++)
  92:                 which += *cp++;
  93:             else
  94:                 cp++;
  95:             continue;
  96: #endif
  97: 
  98:         case '+':
  99:             which += *cp++;
 100:             /* fall into... */
 101: 
 102:         case '.':
 103: casedot:
 104:             /*
 105: 			 * This code is worth scratching your head at for a
 106: 			 * while.  The idea is that various weird things can
 107: 			 * happen to nulls, EOT's, tabs, and newlines by the
 108: 			 * tty driver, arpanet, and so on, so we don't send
 109: 			 * them if we can help it.
 110: 			 *
 111: 			 * Tab is taken out to get Ann Arbors to work, otherwise
 112: 			 * when they go to column 9 we increment which is wrong
 113: 			 * because bcd isn't continuous.  We should take out
 114: 			 * the rest too, or run the thing through more than
 115: 			 * once until it doesn't make any of these, but that
 116: 			 * would make termlib (and hence pdp-11 ex) bigger,
 117: 			 * and also somewhat slower.  This requires all
 118: 			 * programs which use termlib to stty tabs so they
 119: 			 * don't get expanded.  They should do this anyway
 120: 			 * because some terminals use ^I for other things,
 121: 			 * like nondestructive space.
 122: 			 */
 123:             if (which == 0 || which == CTRL(d) || /* which == '\t' || */ which == '\n') {
 124:                 if (oncol || UP) /* Assumption: backspace works */
 125:                     /*
 126: 					 * Loop needed because newline happens
 127: 					 * to be the successor of tab.
 128: 					 */
 129:                     do {
 130:                         strcat(added, oncol ? (BC ? BC : "\b") : UP);
 131:                         which++;
 132:                     } while (which == '\n');
 133:             }
 134:             *dp++ = which;
 135:             goto swap;
 136: 
 137:         case 'r':
 138:             oncol = 1;
 139:             goto setwhich;
 140: 
 141:         case 'i':
 142:             destcol++;
 143:             destline++;
 144:             which++;
 145:             continue;
 146: 
 147:         case '%':
 148:             *dp++ = c;
 149:             continue;
 150: 
 151: #ifdef CM_B
 152:         case 'B':
 153:             which = (which/10 << 4) + which%10;
 154:             continue;
 155: #endif
 156: 
 157: #ifdef CM_D
 158:         case 'D':
 159:             which = which - 2 * (which%16);
 160:             continue;
 161: #endif
 162: 
 163:         default:
 164:             goto toohard;
 165:         }
 166:     }
 167:     strcpy(dp, added);
 168:     return (result);
 169: }

Defined functions

tgoto defined in line 31; used 2 times

Defined variables

BC defined in line 5; used 2 times
  • in line 130(2)
UP defined in line 4; used 2 times

Defined macros

CTRL defined in line 2; used 1 times
Last modified: 1981-07-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 599
Valid CSS Valid XHTML 1.0 Strict