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