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