|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: #define CTRL(c) ('c' & 037) ! 3: #include <stdio.h> ! 4: ! 5: char *UP; ! 6: char *BC; ! 7: ! 8: /* ! 9: * Routine to perform cursor addressing. ! 10: * CM is a string containing printf type escapes to allow ! 11: * cursor addressing. We start out ready to print the destination ! 12: * line, and switch each time we print row or column. ! 13: * The following escapes are defined for substituting row/column: ! 14: * ! 15: * %d as in printf ! 16: * %2 like %2d ! 17: * %3 like %3d ! 18: * %. gives %c hacking special case characters ! 19: * %+x like %c but adding 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[32]; ! 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: char *reason; ! 45: ! 46: fprintf(stderr, "[tgoto: CM '%s', destcol %d, destline %d]\n", CM, destcol, destline); ! 47: if (cp == 0) { ! 48: reason = "cp == 0"; ! 49: toohard: ! 50: /* ! 51: * ``We don't do that under BOZO's big top'' ! 52: */ ! 53: fprintf(stderr, "[OOPS: reason %s]\n", reason); ! 54: return ("OOPS"); ! 55: } ! 56: added[0] = 0; ! 57: while (c = *cp++) { ! 58: if (c != '%') { ! 59: *dp++ = c; ! 60: continue; ! 61: } ! 62: switch (c = *cp++) { ! 63: ! 64: #ifdef CM_N ! 65: case 'n': ! 66: destcol ^= 0140; ! 67: destline ^= 0140; ! 68: goto setwhich; ! 69: #endif ! 70: ! 71: case 'd': ! 72: if (which < 10) ! 73: goto one; ! 74: if (which < 100) ! 75: goto two; ! 76: /* fall into... */ ! 77: ! 78: case '3': ! 79: *dp++ = (which / 100) | '0'; ! 80: which %= 100; ! 81: /* fall into... */ ! 82: ! 83: case '2': ! 84: two: ! 85: *dp++ = which / 10 | '0'; ! 86: one: ! 87: *dp++ = which % 10 | '0'; ! 88: swap: ! 89: oncol = 1 - oncol; ! 90: setwhich: ! 91: which = oncol ? destcol : destline; ! 92: continue; ! 93: ! 94: #ifdef CM_GT ! 95: case '>': ! 96: if (which > *cp++) ! 97: which += *cp++; ! 98: else ! 99: cp++; ! 100: continue; ! 101: #endif ! 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: reason = "X: unknown % code"; ! 170: *reason = c; ! 171: goto toohard; ! 172: } ! 173: } ! 174: strcpy(dp, added); ! 175: return (result); ! 176: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.