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