2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
35 static char sccsid[] = "@(#)tgoto.c 8.1 (Berkeley) 6/4/93";
41 #define CTRL(c) ((c) & 037)
43 #define MAXRETURNSIZE 64
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:
58 * %. gives %c hacking special case characters
59 * %+x like %c but adding x first
61 * The codes below affect the state but don't use up a value.
63 * %>xy if value > x add y
64 * %r reverses row/column
65 * %i increments row/column (for one origin indexing)
67 * %B BCD (2 decimal digits encoded in one byte)
68 * %D Delta Data (backwards bcd)
70 * all other characters are ``self-inserting''.
73 tgoto(const char *CM, int destcol, int destline)
75 static char result[MAXRETURNSIZE];
76 static char added[10];
78 register char *dp = result;
81 register int which = destline;
86 * ``We don't do that under BOZO's big top''
91 while ( (c = *cp++) ) {
93 if (dp >= &result[MAXRETURNSIZE])
115 if (dp >= &result[MAXRETURNSIZE])
117 *dp++ = (which / 100) | '0';
123 if (dp >= &result[MAXRETURNSIZE])
125 *dp++ = which / 10 | '0';
127 if (dp >= &result[MAXRETURNSIZE])
129 *dp++ = which % 10 | '0';
133 which = oncol ? destcol : destline;
152 * This code is worth scratching your head at for a
153 * while. The idea is that various weird things can
154 * happen to nulls, EOT's, tabs, and newlines by the
155 * tty driver, arpanet, and so on, so we don't send
156 * them if we can help it.
158 * Tab is taken out to get Ann Arbors to work, otherwise
159 * when they go to column 9 we increment which is wrong
160 * because bcd isn't continuous. We should take out
161 * the rest too, or run the thing through more than
162 * once until it doesn't make any of these, but that
163 * would make termlib (and hence pdp-11 ex) bigger,
164 * and also somewhat slower. This requires all
165 * programs which use termlib to stty tabs so they
166 * don't get expanded. They should do this anyway
167 * because some terminals use ^I for other things,
168 * like nondestructive space.
170 if (which == 0 || which == CTRL('d') || /* which == '\t' || */ which == '\n') {
171 if (oncol || UP) /* Assumption: backspace works */
173 * Loop needed because newline happens
174 * to be the successor of tab.
179 extra = oncol ? (BC ? BC : "\b") : UP;
180 if (strlen(added) + strlen(extra) >= 10)
182 strcat(added, extra);
184 } while (which == '\n');
186 if (dp >= &result[MAXRETURNSIZE])
202 if (dp >= &result[MAXRETURNSIZE])
209 which = (which/10 << 4) + which%10;
215 which = which - 2 * (which%16);
223 if (strlen(added) >= &result[MAXRETURNSIZE] - dp)