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