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