Commit | Line | Data |
---|---|---|
6468808a | 1 | /* |
31a14b65 KB |
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. | |
6468808a DF |
16 | */ |
17 | ||
760ebb08 | 18 | #ifndef lint |
31a14b65 KB |
19 | static char sccsid[] = "@(#)tgoto.c 5.2 (Berkeley) %G%"; |
20 | #endif /* not lint */ | |
760ebb08 | 21 | |
760ebb08 SL |
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 | } |