|
|
1.1 root 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:
7: #ifndef lint
8: static char sccsid[] = "@(#)tgoto.c 5.1 (Berkeley) 6/5/85";
9: #endif not lint
10:
11: #define CTRL(c) ('c' & 037)
12:
13: #define MAXRETURNSIZE 64
14:
15: char *UP;
16: char *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: */
42: char *
43: tgoto(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) {
56: toohard:
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':
90: two:
91: *dp++ = which / 10 | '0';
92: one:
93: *dp++ = which % 10 | '0';
94: swap:
95: oncol = 1 - oncol;
96: setwhich:
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 '.':
114: casedot:
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.