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