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