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