1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /* Copyright (c) 1979 Regents of the University of California */
31
32 /*LINTLIBRARY*/
33
34 #include <sys/types.h>
35 #include <string.h>
36 #include <sys/ttychars.h>
37
38 #if 0
39 static char
40 sccsid[] = "@(#)tgoto.c 1.5 88/02/08 SMI"; /* from UCB 4.1 6/27/83 */
41 #endif
42
43 #define MAXRETURNSIZE 64
44
45 char *UP;
46 char *BC;
47
48 /*
49 * Routine to perform cursor addressing.
50 * CM is a string containing printf type escapes to allow
51 * cursor addressing. We start out ready to print the destination
52 * line, and switch each time we print row or column.
53 * The following escapes are defined for substituting row/column:
54 *
55 * %d as in printf
56 * %2 like %2d
57 * %3 like %3d
58 * %. gives %c hacking special case characters
59 * %+x like %c but adding x first
60 *
61 * The codes below affect the state but don't use up a value.
62 *
63 * %>xy if value > x add y
64 * %r reverses row/column
65 * %i increments row/column (for one origin indexing)
66 * %% gives %
67 * %B BCD (2 decimal digits encoded in one byte)
68 * %D Delta Data (backwards bcd)
69 *
70 * all other characters are ``self-inserting''.
71 */
72
73 char *
tgoto(char * CM,int destcol,int destline)74 tgoto(char *CM, int destcol, int destline)
75 {
76 static char result[MAXRETURNSIZE];
77 static char added[10];
78 char *cp = CM;
79 char *dp = result;
80 int c;
81 int oncol = 0;
82 int which = destline;
83
84 if (cp == 0) {
85 toohard:
86 /*
87 * ``We don't do that under BOZO's big top''
88 */
89 return ("OOPS");
90 }
91 added[0] = 0;
92 while ((c = *cp++) != 0) {
93 if (c != '%') {
94 *dp++ = (char) c;
95 continue;
96 }
97 switch (c = *cp++) {
98
99 #ifdef CM_N
100 case 'n':
101 destcol ^= 0140;
102 destline ^= 0140;
103 goto setwhich;
104 #endif
105
106 case 'd':
107 if (which < 10)
108 goto one;
109 if (which < 100)
110 goto two;
111 /*FALLTHRU*/
112
113 case '3':
114 *dp++ = (which / 100) | '0';
115 which %= 100;
116 /*FALLTHRU*/
117
118 case '2':
119 two:
120 *dp++ = which / 10 | '0';
121 one:
122 *dp++ = which % 10 | '0';
123 swap:
124 oncol = 1 - oncol;
125 setwhich:
126 which = oncol ? destcol : destline;
127 continue;
128
129 #ifdef CM_GT
130 case '>':
131 if (which > *cp++)
132 which += *cp++;
133 else
134 cp++;
135 continue;
136 #endif
137
138 case '+':
139 which += *cp++;
140 /*FALLTHRU*/
141
142 case '.':
143 /*
144 * This code is worth scratching your head at for a
145 * while. The idea is that various weird things can
146 * happen to nulls, EOT's, tabs, and newlines by the
147 * tty driver, arpanet, and so on, so we don't send
148 * them if we can help it.
149 *
150 * Tab is taken out to get Ann Arbors to work, otherwise
151 * when they go to column 9 we increment which is wrong
152 * because bcd isn't continuous. We should take out
153 * the rest too, or run the thing through more than
154 * once until it doesn't make any of these, but that
155 * would make termlib (and hence pdp-11 ex) bigger,
156 * and also somewhat slower. This requires all
157 * programs which use termlib to stty tabs so they
158 * don't get expanded. They should do this anyway
159 * because some terminals use ^I for other things,
160 * like nondestructive space.
161 */
162 if (which == 0 || which == CTRL('d') || which == '\n') {
163 if (oncol || UP)
164 /* Assumption: backspace works */
165 /*
166 * Loop needed because newline happens
167 * to be the successor of tab.
168 */
169 do {
170 (void) strcat(added, oncol ?
171 (BC ? BC : "\b") : UP);
172 which++;
173 } while (which == '\n');
174 }
175 *dp++ = (char) which;
176 goto swap;
177
178 case 'r':
179 oncol = 1;
180 goto setwhich;
181
182 case 'i':
183 destcol++;
184 destline++;
185 which++;
186 continue;
187
188 case '%':
189 *dp++ = (char) c;
190 continue;
191
192 #ifdef CM_B
193 case 'B':
194 which = (which/10 << 4) + which%10;
195 continue;
196 #endif
197
198 #ifdef CM_D
199 case 'D':
200 which = which - 2 * (which%16);
201 continue;
202 #endif
203
204 default:
205 goto toohard;
206 }
207 }
208 (void) strcpy(dp, added);
209 return (result);
210 }
211