BSD 4_1c_2 release
[unix-history] / usr / src / ucb / ex / ex_get.c
CommitLineData
299f2784 1/* Copyright (c) 1981 Regents of the University of California */
e804469b 2static char *sccsid = "@(#)ex_get.c 7.1 7/8/81";
61b2d8db
MH
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 */
11static bool junkbs;
12short lastc = '\n';
13
14ignchar()
15{
887e3e0d 16 ignore(getchar());
61b2d8db
MH
17}
18
19getchar()
20{
21 register int c;
22
23 do
24 c = getcd();
887e3e0d 25 while (!globp && c == CTRL(d));
61b2d8db
MH
26 return (c);
27}
28
29getcd()
30{
31 register int c;
32
33again:
34 c = getach();
35 if (c == EOF)
36 return (c);
37 c &= TRIM;
38 if (!inopen)
887e3e0d 39 if (!globp && c == CTRL(d))
61b2d8db
MH
40 setlastchar('\n');
41 else if (junk(c)) {
42 checkjunk(c);
43 goto again;
44 }
45 return (c);
46}
47
48peekchar()
49{
50
51 if (peekc == 0)
52 peekc = getchar();
53 return (peekc);
54}
55
56peekcd()
57{
61b2d8db
MH
58 if (peekc == 0)
59 peekc = getcd();
60 return (peekc);
61}
62
63getach()
64{
65 register int c;
66 static char inline[128];
299f2784 67 struct stat statb;
61b2d8db
MH
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 }
80top:
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 }
299f2784
MH
105/* mjm: if (read(0, (char *) &lastc, 1) != 1) CHANGED and added else */
106 if (read(0, inline, 1) != 1)
61b2d8db 107 lastc = EOF;
299f2784
MH
108 else /* mjm: lastc is a short! */
109 lastc = inline[0]; /* mjm: in rightmost 8 bits ! */
61b2d8db
MH
110 return (lastc);
111}
112
113/*
114 * Input routine for insert/append/change in command mode.
115 * Most work here is in handling autoindent.
116 */
117static short lastin;
118
119gettty()
120{
121 register int c = 0;
122 register char *cp = genbuf;
123 char hadup = 0;
124 int numbline();
125 extern int (*Pline)();
126 int offset = Pline == numbline ? 8 : 0;
127 int ch;
128
129 if (intty && !inglobal) {
130 if (offset) {
131 holdcm = 1;
132 printf(" %4d ", lineDOT() + 1);
133 flush();
134 holdcm = 0;
135 }
136 if (value(AUTOINDENT) ^ aiflag) {
137 holdcm = 1;
138#ifdef LISPCODE
139 if (value(LISP))
140 lastin = lindent(dot + 1);
141#endif
142 tab(lastin + offset);
143 while ((c = getcd()) == CTRL(d)) {
144 if (lastin == 0 && isatty(0) == -1) {
145 holdcm = 0;
146 return (EOF);
147 }
148 lastin = backtab(lastin);
149 tab(lastin + offset);
150 }
151 switch (c) {
152
153 case '^':
154 case '0':
155 ch = getcd();
156 if (ch == CTRL(d)) {
157 if (c == '0')
158 lastin = 0;
159 if (!OS) {
160 putchar('\b' | QUOTE);
161 putchar(' ' | QUOTE);
162 putchar('\b' | QUOTE);
163 }
164 tab(offset);
165 hadup = 1;
166 c = getchar();
167 } else
168 ungetchar(ch);
169 break;
170
171 case '.':
172 if (peekchar() == '\n') {
173 ignchar();
174 noteinp();
175 holdcm = 0;
176 return (EOF);
177 }
178 break;
179
180 case '\n':
181 hadup = 1;
182 break;
183 }
184 }
185 flush();
186 holdcm = 0;
187 }
188 if (c == 0)
189 c = getchar();
190 while (c != EOF && c != '\n') {
191 if (cp > &genbuf[LBSIZE - 2])
192 error("Input line too long");
193 *cp++ = c;
194 c = getchar();
195 }
196 if (c == EOF) {
197 if (inglobal)
198 ungetchar(EOF);
199 return (EOF);
200 }
201 *cp = 0;
202 cp = linebuf;
203 if ((value(AUTOINDENT) ^ aiflag) && hadup == 0 && intty && !inglobal) {
204 lastin = c = smunch(lastin, genbuf);
205 for (c = lastin; c >= value(TABSTOP); c -= value(TABSTOP))
206 *cp++ = '\t';
207 for (; c > 0; c--)
208 *cp++ = ' ';
209 }
210 CP(cp, genbuf);
211 if (linebuf[0] == '.' && linebuf[1] == 0)
212 return (EOF);
213 return (0);
214}
215
216/*
217 * Crunch the indent.
218 * Hard thing here is that in command mode some of the indent
219 * is only implicit, so we must seed the column counter.
220 * This should really be done differently so as to use the whitecnt routine
221 * and also to hack indenting for LISP.
222 */
223smunch(col, ocp)
224 register int col;
225 char *ocp;
226{
227 register char *cp;
228
229 cp = ocp;
230 for (;;)
231 switch (*cp++) {
232
233 case ' ':
234 col++;
235 continue;
236
237 case '\t':
238 col += value(TABSTOP) - (col % value(TABSTOP));
239 continue;
240
241 default:
242 cp--;
243 CP(ocp, cp);
244 return (col);
245 }
246}
247
248char *cntrlhm = "^H discarded\n";
249
250checkjunk(c)
251 char c;
252{
253
254 if (junkbs == 0 && c == '\b') {
255 write(2, cntrlhm, 13);
256 junkbs = 1;
257 }
258}
259
260line *
261setin(addr)
262 line *addr;
263{
264
265 if (addr == zero)
266 lastin = 0;
267 else
268 getline(*addr), lastin = smunch(0, linebuf);
269}