xref: /illumos-gate/usr/src/ucblib/libtermcap/tgoto.c (revision 99653d4ee642c6528e88224f12409a5f23060994)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
33 
34 /*LINTLIBRARY*/
35 
36 #include <sys/types.h>
37 #include <string.h>
38 #include <sys/ttychars.h>
39 
40 #if 0
41 static char
42 sccsid[] = "@(#)tgoto.c 1.5 88/02/08 SMI"; /* from UCB 4.1 6/27/83 */
43 #endif
44 
45 #define	MAXRETURNSIZE 64
46 
47 char	*UP;
48 char	*BC;
49 
50 /*
51  * Routine to perform cursor addressing.
52  * CM is a string containing printf type escapes to allow
53  * cursor addressing.  We start out ready to print the destination
54  * line, and switch each time we print row or column.
55  * The following escapes are defined for substituting row/column:
56  *
57  *	%d	as in printf
58  *	%2	like %2d
59  *	%3	like %3d
60  *	%.	gives %c hacking special case characters
61  *	%+x	like %c but adding x first
62  *
63  *	The codes below affect the state but don't use up a value.
64  *
65  *	%>xy	if value > x add y
66  *	%r	reverses row/column
67  *	%i	increments row/column (for one origin indexing)
68  *	%%	gives %
69  *	%B	BCD (2 decimal digits encoded in one byte)
70  *	%D	Delta Data (backwards bcd)
71  *
72  * all other characters are ``self-inserting''.
73  */
74 
75 char *
76 tgoto(char *CM, int destcol, int destline)
77 {
78 	static char result[MAXRETURNSIZE];
79 	static char added[10];
80 	char *cp = CM;
81 	char *dp = result;
82 	int c;
83 	int oncol = 0;
84 	int which = destline;
85 
86 	if (cp == 0) {
87 toohard:
88 		/*
89 		 * ``We don't do that under BOZO's big top''
90 		 */
91 		return ("OOPS");
92 	}
93 	added[0] = 0;
94 	while ((c = *cp++) != 0) {
95 		if (c != '%') {
96 			*dp++ = (char) c;
97 			continue;
98 		}
99 		switch (c = *cp++) {
100 
101 #ifdef CM_N
102 		case 'n':
103 			destcol ^= 0140;
104 			destline ^= 0140;
105 			goto setwhich;
106 #endif
107 
108 		case 'd':
109 			if (which < 10)
110 				goto one;
111 			if (which < 100)
112 				goto two;
113 			/*FALLTHRU*/
114 
115 		case '3':
116 			*dp++ = (which / 100) | '0';
117 			which %= 100;
118 			/*FALLTHRU*/
119 
120 		case '2':
121 two:
122 			*dp++ = which / 10 | '0';
123 one:
124 			*dp++ = which % 10 | '0';
125 swap:
126 			oncol = 1 - oncol;
127 setwhich:
128 			which = oncol ? destcol : destline;
129 			continue;
130 
131 #ifdef CM_GT
132 		case '>':
133 			if (which > *cp++)
134 				which += *cp++;
135 			else
136 				cp++;
137 			continue;
138 #endif
139 
140 		case '+':
141 			which += *cp++;
142 			/*FALLTHRU*/
143 
144 		case '.':
145 			/*
146 			 * This code is worth scratching your head at for a
147 			 * while.  The idea is that various weird things can
148 			 * happen to nulls, EOT's, tabs, and newlines by the
149 			 * tty driver, arpanet, and so on, so we don't send
150 			 * them if we can help it.
151 			 *
152 			 * Tab is taken out to get Ann Arbors to work, otherwise
153 			 * when they go to column 9 we increment which is wrong
154 			 * because bcd isn't continuous.  We should take out
155 			 * the rest too, or run the thing through more than
156 			 * once until it doesn't make any of these, but that
157 			 * would make termlib (and hence pdp-11 ex) bigger,
158 			 * and also somewhat slower.  This requires all
159 			 * programs which use termlib to stty tabs so they
160 			 * don't get expanded.  They should do this anyway
161 			 * because some terminals use ^I for other things,
162 			 * like nondestructive space.
163 			 */
164 			if (which == 0 || which == CTRL('d') || which == '\n') {
165 				if (oncol || UP)
166 					/* Assumption: backspace works */
167 					/*
168 					 * Loop needed because newline happens
169 					 * to be the successor of tab.
170 					 */
171 					do {
172 						(void) strcat(added, oncol ?
173 							(BC ? BC : "\b") : UP);
174 						which++;
175 					} while (which == '\n');
176 			}
177 			*dp++ = (char) which;
178 			goto swap;
179 
180 		case 'r':
181 			oncol = 1;
182 			goto setwhich;
183 
184 		case 'i':
185 			destcol++;
186 			destline++;
187 			which++;
188 			continue;
189 
190 		case '%':
191 			*dp++ = (char) c;
192 			continue;
193 
194 #ifdef CM_B
195 		case 'B':
196 			which = (which/10 << 4) + which%10;
197 			continue;
198 #endif
199 
200 #ifdef CM_D
201 		case 'D':
202 			which = which - 2 * (which%16);
203 			continue;
204 #endif
205 
206 		default:
207 			goto toohard;
208 		}
209 	}
210 	(void) strcpy(dp, added);
211 	return (result);
212 }
213