|
|
1.1 root 1: /* Copyright (c) 1980 Regents of the University of California */
2: static char *sccsid = "@(#)ex_get.c 6.1 10/18/80";
3: #include "ex.h"
4: #include "ex_tty.h"
5:
6: /*
7: * Input routines for command mode.
8: * Since we translate the end of reads into the implied ^D's
9: * we have different flavors of routines which do/don't return such.
10: */
11: static bool junkbs;
12: short lastc = '\n';
13:
14: ignchar()
15: {
16: ignore(getchar());
17: }
18:
19: getchar()
20: {
21: register int c;
22:
23: do
24: c = getcd();
25: while (!globp && c == CTRL(d));
26: return (c);
27: }
28:
29: getcd()
30: {
31: register int c;
32:
33: again:
34: c = getach();
35: if (c == EOF)
36: return (c);
37: c &= TRIM;
38: if (!inopen)
39: if (!globp && c == CTRL(d))
40: setlastchar('\n');
41: else if (junk(c)) {
42: checkjunk(c);
43: goto again;
44: }
45: return (c);
46: }
47:
48: peekchar()
49: {
50:
51: if (peekc == 0)
52: peekc = getchar();
53: return (peekc);
54: }
55:
56: peekcd()
57: {
58:
59: if (peekc == 0)
60: peekc = getcd();
61: return (peekc);
62: }
63:
64: getach()
65: {
66: register int c;
67: static char inline[128];
68:
69: c = peekc;
70: if (c != 0) {
71: peekc = 0;
72: return (c);
73: }
74: if (globp) {
75: if (*globp)
76: return (*globp++);
77: globp = 0;
78: return (lastc = EOF);
79: }
80: top:
81: if (input) {
82: if (c = *input++) {
83: if (c &= TRIM)
84: return (lastc = c);
85: goto top;
86: }
87: input = 0;
88: }
89: flush();
90: if (intty) {
91: c = read(0, inline, sizeof inline - 4);
92: if (c < 0)
93: return (lastc = EOF);
94: if (c == 0 || inline[c-1] != '\n')
95: inline[c++] = CTRL(d);
96: if (inline[c-1] == '\n')
97: noteinp();
98: inline[c] = 0;
99: for (c--; c >= 0; c--)
100: if (inline[c] == 0)
101: inline[c] = QUOTE;
102: input = inline;
103: goto top;
104: }
105: if (read(0, (char *) &lastc, 1) != 1)
106: lastc = EOF;
107: return (lastc);
108: }
109:
110: /*
111: * Input routine for insert/append/change in command mode.
112: * Most work here is in handling autoindent.
113: */
114: static short lastin;
115:
116: gettty()
117: {
118: register int c = 0;
119: register char *cp = genbuf;
120: char hadup = 0;
121: int numbline();
122: extern int (*Pline)();
123: int offset = Pline == numbline ? 8 : 0;
124: int ch;
125:
126: if (intty && !inglobal) {
127: if (offset) {
128: holdcm = 1;
129: printf(" %4d ", lineDOT() + 1);
130: flush();
131: holdcm = 0;
132: }
133: if (value(AUTOINDENT) ^ aiflag) {
134: holdcm = 1;
135: #ifdef LISPCODE
136: if (value(LISP))
137: lastin = lindent(dot + 1);
138: #endif
139: tab(lastin + offset);
140: while ((c = getcd()) == CTRL(d)) {
141: if (lastin == 0 && isatty(0) == -1) {
142: holdcm = 0;
143: return (EOF);
144: }
145: lastin = backtab(lastin);
146: tab(lastin + offset);
147: }
148: switch (c) {
149:
150: case '^':
151: case '0':
152: ch = getcd();
153: if (ch == CTRL(d)) {
154: if (c == '0')
155: lastin = 0;
156: if (!OS) {
157: putchar('\b' | QUOTE);
158: putchar(' ' | QUOTE);
159: putchar('\b' | QUOTE);
160: }
161: tab(offset);
162: hadup = 1;
163: c = getchar();
164: } else
165: ungetchar(ch);
166: break;
167:
168: case '.':
169: if (peekchar() == '\n') {
170: ignchar();
171: noteinp();
172: holdcm = 0;
173: return (EOF);
174: }
175: break;
176:
177: case '\n':
178: hadup = 1;
179: break;
180: }
181: }
182: flush();
183: holdcm = 0;
184: }
185: if (c == 0)
186: c = getchar();
187: while (c != EOF && c != '\n') {
188: if (cp > &genbuf[LBSIZE - 2])
189: error("Input line too long");
190: *cp++ = c;
191: c = getchar();
192: }
193: if (c == EOF) {
194: if (inglobal)
195: ungetchar(EOF);
196: return (EOF);
197: }
198: *cp = 0;
199: cp = linebuf;
200: if ((value(AUTOINDENT) ^ aiflag) && hadup == 0 && intty && !inglobal) {
201: lastin = c = smunch(lastin, genbuf);
202: for (c = lastin; c >= value(TABSTOP); c -= value(TABSTOP))
203: *cp++ = '\t';
204: for (; c > 0; c--)
205: *cp++ = ' ';
206: }
207: CP(cp, genbuf);
208: if (linebuf[0] == '.' && linebuf[1] == 0)
209: return (EOF);
210: return (0);
211: }
212:
213: /*
214: * Crunch the indent.
215: * Hard thing here is that in command mode some of the indent
216: * is only implicit, so we must seed the column counter.
217: * This should really be done differently so as to use the whitecnt routine
218: * and also to hack indenting for LISP.
219: */
220: smunch(col, ocp)
221: register int col;
222: char *ocp;
223: {
224: register char *cp;
225:
226: cp = ocp;
227: for (;;)
228: switch (*cp++) {
229:
230: case ' ':
231: col++;
232: continue;
233:
234: case '\t':
235: col += value(TABSTOP) - (col % value(TABSTOP));
236: continue;
237:
238: default:
239: cp--;
240: CP(ocp, cp);
241: return (col);
242: }
243: }
244:
245: char *cntrlhm = "^H discarded\n";
246:
247: checkjunk(c)
248: char c;
249: {
250:
251: if (junkbs == 0 && c == '\b') {
252: write(2, cntrlhm, 13);
253: junkbs = 1;
254: }
255: }
256:
257: line *
258: setin(addr)
259: line *addr;
260: {
261:
262: if (addr == zero)
263: lastin = 0;
264: else
265: getline(*addr), lastin = smunch(0, linebuf);
266: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.