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