|
|
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: * ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.