|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #define CTRL(c) ('c' & 037)
3: #include <stdio.h>
4:
5: char *UP;
6: char *BC;
7:
8: /*
9: * Routine to perform cursor addressing.
10: * CM is a string containing printf type escapes to allow
11: * cursor addressing. We start out ready to print the destination
12: * line, and switch each time we print row or column.
13: * The following escapes are defined for substituting row/column:
14: *
15: * %d as in printf
16: * %2 like %2d
17: * %3 like %3d
18: * %. gives %c hacking special case characters
19: * %+x like %c but adding 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[32];
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: char *reason;
45:
46: fprintf(stderr, "[tgoto: CM '%s', destcol %d, destline %d]\n", CM, destcol, destline);
47: if (cp == 0) {
48: reason = "cp == 0";
49: toohard:
50: /*
51: * ``We don't do that under BOZO's big top''
52: */
53: fprintf(stderr, "[OOPS: reason %s]\n", reason);
54: return ("OOPS");
55: }
56: added[0] = 0;
57: while (c = *cp++) {
58: if (c != '%') {
59: *dp++ = c;
60: continue;
61: }
62: switch (c = *cp++) {
63:
64: #ifdef CM_N
65: case 'n':
66: destcol ^= 0140;
67: destline ^= 0140;
68: goto setwhich;
69: #endif
70:
71: case 'd':
72: if (which < 10)
73: goto one;
74: if (which < 100)
75: goto two;
76: /* fall into... */
77:
78: case '3':
79: *dp++ = (which / 100) | '0';
80: which %= 100;
81: /* fall into... */
82:
83: case '2':
84: two:
85: *dp++ = which / 10 | '0';
86: one:
87: *dp++ = which % 10 | '0';
88: swap:
89: oncol = 1 - oncol;
90: setwhich:
91: which = oncol ? destcol : destline;
92: continue;
93:
94: #ifdef CM_GT
95: case '>':
96: if (which > *cp++)
97: which += *cp++;
98: else
99: cp++;
100: continue;
101: #endif
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: reason = "X: unknown % code";
170: *reason = c;
171: goto toohard;
172: }
173: }
174: strcpy(dp, added);
175: return (result);
176: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.