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