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