Subversion Repositories planix.SVN

Rev

Rev 113 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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