Subversion Repositories planix.SVN

Rev

Rev 113 | Rev 116 | Go to most recent revision | Details | Compare with Previous | 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_set.c	7.4 (Berkeley) 6/7/85";
9
#endif
10
 
11
#include "ex.h"
12
#include "ex_temp.h"
13
#include "ex_tty.h"
14
 
15
/*
16
 * Set command.
17
 */
18
char	optname[ONMSZ];
19
 
20
set()
21
{
22
	register char *cp;
23
	register struct option *op;
24
	register int c;
25
	bool no;
26
	extern short o_speed;
27
 
28
	setnoaddr();
29
	if (skipend()) {
30
		if (peekchar() != EOF)
31
			ignchar();
32
		propts();
33
		return;
34
	}
35
	do {
36
		cp = optname;
37
		do {
38
			if (cp < &optname[ONMSZ - 2])
39
				*cp++ = getchar();
40
		} while (isalnum(peekchar()));
41
		*cp = 0;
42
		cp = optname;
43
		if (eq("all", cp)) {
44
			if (inopen)
45
				pofix();
46
			prall();
47
			goto next;
48
		}
49
		no = 0;
50
		if (cp[0] == 'n' && cp[1] == 'o') {
51
			cp += 2;
52
			no++;
53
		}
54
		/* Implement w300, w1200, and w9600 specially */
55
		if (eq(cp, "w300")) {
56
			if (o_speed >= B1200) {
57
dontset:
58
				ignore(getchar());	/* = */
59
				ignore(getnum());	/* value */
60
				continue;
61
			}
62
			cp = "window";
63
		} else if (eq(cp, "w1200")) {
64
			if (o_speed < B1200 || o_speed >= B2400)
65
				goto dontset;
66
			cp = "window";
67
		} else if (eq(cp, "w9600")) {
68
			if (o_speed < B2400)
69
				goto dontset;
70
			cp = "window";
71
		}
72
		for (op = options; op < &options[NOPTS]; op++)
73
			if (eq(op->oname, cp) || op->oabbrev && eq(op->oabbrev, cp))
74
				break;
75
		if (op->oname == 0)
76
			serror("%s: No such option@- 'set all' gives all option values", cp);
77
		c = skipwh();
78
		if (peekchar() == '?') {
79
			ignchar();
80
printone:
81
			propt(op);
82
			noonl();
83
			goto next;
84
		}
85
		if (op->otype == ONOFF) {
86
			op->ovalue = 1 - no;
87
			if (op == &options[PROMPT])
88
				oprompt = 1 - no;
89
			goto next;
90
		}
91
		if (no)
92
			serror("Option %s is not a toggle", op->oname);
93
		if (c != 0 || setend())
94
			goto printone;
95
		if (getchar() != '=')
96
			serror("Missing =@in assignment to option %s", op->oname);
97
		switch (op->otype) {
98
 
99
		case NUMERIC:
100
			if (!isdigit(peekchar()))
101
				error("Digits required@after =");
102
			op->ovalue = getnum();
103
			if (value(TABSTOP) <= 0)
104
				value(TABSTOP) = TABS;
105
			if (value(HARDTABS) <= 0)
106
				value(HARDTABS) = TABS;
107
			if (op == &options[WINDOW]) {
108
				if (value(WINDOW) >= LINES)
109
					value(WINDOW) = LINES-1;
110
				vsetsiz(value(WINDOW));
111
			}
112
			break;
113
 
114
		case STRING:
115
		case OTERM:
116
			cp = optname;
117
			while (!setend()) {
118
				if (cp >= &optname[ONMSZ])
119
					error("String too long@in option assignment");
120
				/* adb change:  allow whitepace in strings */
121
				if( (*cp = getchar()) == '\\')
122
					if( peekchar() != EOF)
123
						*cp = getchar();
124
				cp++;
125
			}
126
			*cp = 0;
127
			if (op->otype == OTERM) {
128
/*
129
 * At first glance it seems like we shouldn't care if the terminal type
130
 * is changed inside visual mode, as long as we assume the screen is
131
 * a mess and redraw it. However, it's a much harder problem than that.
132
 * If you happen to change from 1 crt to another that both have the same
133
 * size screen, it's OK. But if the screen size if different, the stuff
134
 * that gets initialized in vop() will be wrong. This could be overcome
135
 * by redoing the initialization, e.g. making the first 90% of vop into
136
 * a subroutine. However, the most useful case is where you forgot to do
137
 * a setenv before you went into the editor and it thinks you're on a dumb
138
 * terminal. Ex treats this like hardcopy and goes into HARDOPEN mode.
139
 * This loses because the first part of vop calls oop in this case.
140
 * The problem is so hard I gave up. I'm not saying it can't be done,
141
 * but I am saying it probably isn't worth the effort.
142
 */
143
				if (inopen)
144
error("Can't change type of terminal from within open/visual");
145
				setterm(optname);
146
			} else {
115 7u83 147
				CP(op->osvalue, optname);
105 7u83 148
				op->odefault = 1;
149
			}
150
			break;
151
		}
152
next:
153
		flush();
154
	} while (!skipend());
155
	eol();
156
}
157
 
158
setend()
159
{
160
 
161
	return (iswhite(peekchar()) || endcmd(peekchar()));
162
}
163
 
164
prall()
165
{
166
	register int incr = (NOPTS + 2) / 3;
167
	register int rows = incr;
168
	register struct option *op = options;
169
 
170
	for (; rows; rows--, op++) {
171
		propt(op);
172
		tab(24);
173
		propt(&op[incr]);
174
		if (&op[2*incr] < &options[NOPTS]) {
175
			tab(56);
176
			propt(&op[2 * incr]);
177
		}
178
		putNFL();
179
	}
180
}
181
 
182
propts()
183
{
184
	register struct option *op;
185
 
186
	for (op = options; op < &options[NOPTS]; op++) {
187
#ifdef V6
188
		if (op == &options[TERM])
189
#else
190
		if (op == &options[TTYTYPE])
191
#endif
192
			continue;
193
		switch (op->otype) {
194
 
195
		case ONOFF:
196
		case NUMERIC:
197
			if (op->ovalue == op->odefault)
198
				continue;
199
			break;
200
 
201
		case STRING:
202
			if (op->odefault == 0)
203
				continue;
204
			break;
205
		}
206
		propt(op);
207
		putchar(' ');
208
	}
209
	noonl();
210
	flush();
211
}
212
 
213
propt(op)
214
	register struct option *op;
215
{
216
	register char *name;
217
 
218
	name = op->oname;
219
 
220
	switch (op->otype) {
221
 
222
	case ONOFF:
223
		printf("%s%s", op->ovalue ? "" : "no", name);
224
		break;
225
 
226
	case NUMERIC:
227
		printf("%s=%d", name, op->ovalue);
228
		break;
229
 
230
	case STRING:
231
	case OTERM:
232
		printf("%s=%s", name, op->osvalue);
233
		break;
234
	}
235
}