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