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