Commit | Line | Data |
---|---|---|
299f2784 MH |
1 | /* Copyright (c) 1981 Regents of the University of California */ |
2 | static char *sccsid = "@(#)ex_get.c 7.1 %G%"; | |
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 | */ | |
11 | static bool junkbs; | |
12 | short lastc = '\n'; | |
13 | ||
14 | ignchar() | |
15 | { | |
887e3e0d | 16 | ignore(getchar()); |
61b2d8db MH |
17 | } |
18 | ||
19 | getchar() | |
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 | ||
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) | |
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 | ||
48 | peekchar() | |
49 | { | |
50 | ||
51 | if (peekc == 0) | |
52 | peekc = getchar(); | |
53 | return (peekc); | |
54 | } | |
55 | ||
56 | peekcd() | |
57 | { | |
61b2d8db MH |
58 | if (peekc == 0) |
59 | peekc = getcd(); | |
60 | return (peekc); | |
61 | } | |
62 | ||
63 | getach() | |
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 | } | |
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 | } | |
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 | */ | |
117 | static short lastin; | |
118 | ||
119 | gettty() | |
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 | */ | |
223 | smunch(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 | ||
248 | char *cntrlhm = "^H discarded\n"; | |
249 | ||
250 | checkjunk(c) | |
251 | char c; | |
252 | { | |
253 | ||
254 | if (junkbs == 0 && c == '\b') { | |
255 | write(2, cntrlhm, 13); | |
256 | junkbs = 1; | |
257 | } | |
258 | } | |
259 | ||
260 | line * | |
261 | setin(addr) | |
262 | line *addr; | |
263 | { | |
264 | ||
265 | if (addr == zero) | |
266 | lastin = 0; | |
267 | else | |
268 | getline(*addr), lastin = smunch(0, linebuf); | |
269 | } |