BSD 4_3 release
[unix-history] / usr / src / ucb / ex / ex_get.c
CommitLineData
19d73a0e
DF
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
95f51977 8static char *sccsid = "@(#)ex_get.c 7.6 (Berkeley) 6/7/85";
19d73a0e
DF
9#endif not lint
10
61b2d8db
MH
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 */
19static bool junkbs;
20short lastc = '\n';
21
22ignchar()
23{
887e3e0d 24 ignore(getchar());
61b2d8db
MH
25}
26
27getchar()
28{
29 register int c;
30
31 do
32 c = getcd();
887e3e0d 33 while (!globp && c == CTRL(d));
61b2d8db
MH
34 return (c);
35}
36
37getcd()
38{
39 register int c;
40
41again:
42 c = getach();
43 if (c == EOF)
44 return (c);
45 c &= TRIM;
46 if (!inopen)
887e3e0d 47 if (!globp && c == CTRL(d))
61b2d8db
MH
48 setlastchar('\n');
49 else if (junk(c)) {
50 checkjunk(c);
51 goto again;
52 }
53 return (c);
54}
55
56peekchar()
57{
58
59 if (peekc == 0)
60 peekc = getchar();
61 return (peekc);
62}
63
64peekcd()
65{
61b2d8db
MH
66 if (peekc == 0)
67 peekc = getcd();
68 return (peekc);
69}
70
71getach()
72{
73 register int c;
0567d6e3 74 static char inline[BUFSIZ];
299f2784 75 struct stat statb;
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 }
88top:
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) {
61b2d8db
MH
99 c = read(0, inline, sizeof inline - 4);
100 if (c < 0)
101 return (lastc = EOF);
102 if (c == 0 || inline[c-1] != '\n')
103 inline[c++] = CTRL(d);
104 if (inline[c-1] == '\n')
105 noteinp();
106 inline[c] = 0;
107 for (c--; c >= 0; c--)
108 if (inline[c] == 0)
109 inline[c] = QUOTE;
110 input = inline;
111 goto top;
112 }
f4f348a0 113 c = read(0, inline, sizeof inline - 1);
0567d6e3
RC
114 if(c <= 0)
115 return(lastc = EOF);
f4f348a0 116 inline[c] = '\0';
0567d6e3
RC
117 input = inline;
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 */
125static short lastin;
126
127gettty()
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;
140 printf(" %4d ", lineDOT() + 1);
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);
151 while ((c = getcd()) == CTRL(d)) {
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();
164 if (ch == CTRL(d)) {
165 if (c == '0')
166 lastin = 0;
167 if (!OS) {
168 putchar('\b' | QUOTE);
169 putchar(' ' | QUOTE);
170 putchar('\b' | QUOTE);
171 }
172 tab(offset);
173 hadup = 1;
174 c = getchar();
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)
197 c = getchar();
198 while (c != EOF && c != '\n') {
199 if (cp > &genbuf[LBSIZE - 2])
200 error("Input line too long");
201 *cp++ = c;
202 c = getchar();
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 */
231smunch(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
256char *cntrlhm = "^H discarded\n";
257
258checkjunk(c)
259 char c;
260{
261
262 if (junkbs == 0 && c == '\b') {
263 write(2, cntrlhm, 13);
264 junkbs = 1;
265 }
266}
267
268line *
269setin(addr)
270 line *addr;
271{
272
273 if (addr == zero)
274 lastin = 0;
275 else
276 getline(*addr), lastin = smunch(0, linebuf);
277}