../machine => machine
[unix-history] / usr / src / lib / libterm / tgoto.c
CommitLineData
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
19static 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
26char *UP;
27char *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 */
53char *
54tgoto(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) {
67toohard:
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':
101two:
102 *dp++ = which / 10 | '0';
103one:
104 *dp++ = which % 10 | '0';
105swap:
106 oncol = 1 - oncol;
107setwhich:
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 '.':
125casedot:
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}