new copyright notice
[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 *
9c1340a5 5 * %sccs.include.redist.c%
6468808a
DF
6 */
7
760ebb08 8#ifndef lint
9c1340a5 9static char sccsid[] = "@(#)tgoto.c 5.4 (Berkeley) %G%";
31a14b65 10#endif /* not lint */
760ebb08 11
3d5c63f1 12#define CTRL(c) ((c) & 037)
760ebb08
SL
13
14#define MAXRETURNSIZE 64
15
16char *UP;
17char *BC;
18
19/*
20 * Routine to perform cursor addressing.
21 * CM is a string containing printf type escapes to allow
22 * cursor addressing. We start out ready to print the destination
23 * line, and switch each time we print row or column.
24 * The following escapes are defined for substituting row/column:
25 *
26 * %d as in printf
27 * %2 like %2d
28 * %3 like %3d
29 * %. gives %c hacking special case characters
30 * %+x like %c but adding x first
31 *
32 * The codes below affect the state but don't use up a value.
33 *
34 * %>xy if value > x add y
35 * %r reverses row/column
36 * %i increments row/column (for one origin indexing)
37 * %% gives %
38 * %B BCD (2 decimal digits encoded in one byte)
39 * %D Delta Data (backwards bcd)
40 *
41 * all other characters are ``self-inserting''.
42 */
43char *
44tgoto(CM, destcol, destline)
45 char *CM;
46 int destcol, destline;
47{
48 static char result[MAXRETURNSIZE];
49 static char added[10];
50 char *cp = CM;
51 register char *dp = result;
52 register int c;
53 int oncol = 0;
54 register int which = destline;
55
56 if (cp == 0) {
57toohard:
58 /*
59 * ``We don't do that under BOZO's big top''
60 */
61 return ("OOPS");
62 }
63 added[0] = 0;
64 while (c = *cp++) {
65 if (c != '%') {
66 *dp++ = c;
67 continue;
68 }
69 switch (c = *cp++) {
70
71#ifdef CM_N
72 case 'n':
73 destcol ^= 0140;
74 destline ^= 0140;
75 goto setwhich;
76#endif
77
78 case 'd':
79 if (which < 10)
80 goto one;
81 if (which < 100)
82 goto two;
83 /* fall into... */
84
85 case '3':
86 *dp++ = (which / 100) | '0';
87 which %= 100;
88 /* fall into... */
89
90 case '2':
91two:
92 *dp++ = which / 10 | '0';
93one:
94 *dp++ = which % 10 | '0';
95swap:
96 oncol = 1 - oncol;
97setwhich:
98 which = oncol ? destcol : destline;
99 continue;
100
101#ifdef CM_GT
102 case '>':
103 if (which > *cp++)
104 which += *cp++;
105 else
106 cp++;
107 continue;
108#endif
109
110 case '+':
111 which += *cp++;
112 /* fall into... */
113
114 case '.':
115casedot:
116 /*
117 * This code is worth scratching your head at for a
118 * while. The idea is that various weird things can
119 * happen to nulls, EOT's, tabs, and newlines by the
120 * tty driver, arpanet, and so on, so we don't send
121 * them if we can help it.
122 *
123 * Tab is taken out to get Ann Arbors to work, otherwise
124 * when they go to column 9 we increment which is wrong
125 * because bcd isn't continuous. We should take out
126 * the rest too, or run the thing through more than
127 * once until it doesn't make any of these, but that
128 * would make termlib (and hence pdp-11 ex) bigger,
129 * and also somewhat slower. This requires all
130 * programs which use termlib to stty tabs so they
131 * don't get expanded. They should do this anyway
132 * because some terminals use ^I for other things,
133 * like nondestructive space.
134 */
3d5c63f1 135 if (which == 0 || which == CTRL('d') || /* which == '\t' || */ which == '\n') {
760ebb08
SL
136 if (oncol || UP) /* Assumption: backspace works */
137 /*
138 * Loop needed because newline happens
139 * to be the successor of tab.
140 */
141 do {
142 strcat(added, oncol ? (BC ? BC : "\b") : UP);
143 which++;
144 } while (which == '\n');
145 }
146 *dp++ = which;
147 goto swap;
148
149 case 'r':
150 oncol = 1;
151 goto setwhich;
152
153 case 'i':
154 destcol++;
155 destline++;
156 which++;
157 continue;
158
159 case '%':
160 *dp++ = c;
161 continue;
162
163#ifdef CM_B
164 case 'B':
165 which = (which/10 << 4) + which%10;
166 continue;
167#endif
168
169#ifdef CM_D
170 case 'D':
171 which = which - 2 * (which%16);
172 continue;
173#endif
174
175 default:
176 goto toohard;
177 }
178 }
179 strcpy(dp, added);
180 return (result);
181}