xref: /csrg-svn/usr.bin/ex/ex_set.c (revision 63046)
148255Sbostic /*-
2*63046Sbostic  * Copyright (c) 1980, 1993
3*63046Sbostic  *	The Regents of the University of California.  All rights reserved.
448255Sbostic  *
548255Sbostic  * %sccs.include.proprietary.c%
621664Sdist  */
721664Sdist 
821664Sdist #ifndef lint
9*63046Sbostic static char sccsid[] = "@(#)ex_set.c	8.1 (Berkeley) 06/09/93";
1048255Sbostic #endif /* not lint */
1121664Sdist 
12440Smark #include "ex.h"
13440Smark #include "ex_temp.h"
1421689Sdist #include "ex_tty.h"
15440Smark 
16440Smark /*
17440Smark  * Set command.
18440Smark  */
19440Smark char	optname[ONMSZ];
20440Smark 
set()21440Smark set()
22440Smark {
23440Smark 	register char *cp;
24440Smark 	register struct option *op;
25440Smark 	register int c;
26440Smark 	bool no;
27493Smark 	extern short ospeed;
28440Smark 
29440Smark 	setnoaddr();
30440Smark 	if (skipend()) {
31440Smark 		if (peekchar() != EOF)
32440Smark 			ignchar();
33440Smark 		propts();
34440Smark 		return;
35440Smark 	}
36440Smark 	do {
37440Smark 		cp = optname;
38440Smark 		do {
39440Smark 			if (cp < &optname[ONMSZ - 2])
4030596Sconrad 				*cp++ = ex_getchar();
41493Smark 		} while (isalnum(peekchar()));
42440Smark 		*cp = 0;
43440Smark 		cp = optname;
44440Smark 		if (eq("all", cp)) {
45440Smark 			if (inopen)
46440Smark 				pofix();
47440Smark 			prall();
48440Smark 			goto next;
49440Smark 		}
50440Smark 		no = 0;
51440Smark 		if (cp[0] == 'n' && cp[1] == 'o') {
52440Smark 			cp += 2;
53440Smark 			no++;
54440Smark 		}
55493Smark 		/* Implement w300, w1200, and w9600 specially */
56493Smark 		if (eq(cp, "w300")) {
57493Smark 			if (ospeed >= B1200) {
58493Smark dontset:
5930596Sconrad 				ignore(ex_getchar());	/* = */
60493Smark 				ignore(getnum());	/* value */
61493Smark 				continue;
62493Smark 			}
63493Smark 			cp = "window";
64493Smark 		} else if (eq(cp, "w1200")) {
65493Smark 			if (ospeed < B1200 || ospeed >= B2400)
66493Smark 				goto dontset;
67493Smark 			cp = "window";
68493Smark 		} else if (eq(cp, "w9600")) {
69493Smark 			if (ospeed < B2400)
70493Smark 				goto dontset;
71493Smark 			cp = "window";
72493Smark 		}
73440Smark 		for (op = options; op < &options[NOPTS]; op++)
74440Smark 			if (eq(op->oname, cp) || op->oabbrev && eq(op->oabbrev, cp))
75440Smark 				break;
76440Smark 		if (op->oname == 0)
77440Smark 			serror("%s: No such option@- 'set all' gives all option values", cp);
78440Smark 		c = skipwh();
79440Smark 		if (peekchar() == '?') {
80440Smark 			ignchar();
81440Smark printone:
82440Smark 			propt(op);
83440Smark 			noonl();
84440Smark 			goto next;
85440Smark 		}
86440Smark 		if (op->otype == ONOFF) {
87440Smark 			op->ovalue = 1 - no;
88519Smark 			if (op == &options[PROMPT])
89519Smark 				oprompt = 1 - no;
90440Smark 			goto next;
91440Smark 		}
92440Smark 		if (no)
93440Smark 			serror("Option %s is not a toggle", op->oname);
94440Smark 		if (c != 0 || setend())
95440Smark 			goto printone;
9630596Sconrad 		if (ex_getchar() != '=')
97440Smark 			serror("Missing =@in assignment to option %s", op->oname);
98440Smark 		switch (op->otype) {
99440Smark 
100440Smark 		case NUMERIC:
101440Smark 			if (!isdigit(peekchar()))
102493Smark 				error("Digits required@after =");
103440Smark 			op->ovalue = getnum();
104440Smark 			if (value(TABSTOP) <= 0)
105440Smark 				value(TABSTOP) = TABS;
10621689Sdist 			if (value(HARDTABS) <= 0)
10721689Sdist 				value(HARDTABS) = TABS;
10821689Sdist 			if (op == &options[WINDOW]) {
10921689Sdist 				if (value(WINDOW) >= LINES)
11021689Sdist 					value(WINDOW) = LINES-1;
111493Smark 				vsetsiz(value(WINDOW));
11221689Sdist 			}
113440Smark 			break;
114440Smark 
115440Smark 		case STRING:
116440Smark 		case OTERM:
117440Smark 			cp = optname;
118440Smark 			while (!setend()) {
119440Smark 				if (cp >= &optname[ONMSZ])
120440Smark 					error("String too long@in option assignment");
121440Smark 				/* adb change:  allow whitepace in strings */
12230596Sconrad 				if( (*cp = ex_getchar()) == '\\')
123440Smark 					if( peekchar() != EOF)
12430596Sconrad 						*cp = ex_getchar();
125440Smark 				cp++;
126440Smark 			}
127440Smark 			*cp = 0;
128440Smark 			if (op->otype == OTERM) {
129440Smark /*
130440Smark  * At first glance it seems like we shouldn't care if the terminal type
131440Smark  * is changed inside visual mode, as long as we assume the screen is
132440Smark  * a mess and redraw it. However, it's a much harder problem than that.
133440Smark  * If you happen to change from 1 crt to another that both have the same
134440Smark  * size screen, it's OK. But if the screen size if different, the stuff
135440Smark  * that gets initialized in vop() will be wrong. This could be overcome
136440Smark  * by redoing the initialization, e.g. making the first 90% of vop into
137440Smark  * a subroutine. However, the most useful case is where you forgot to do
138440Smark  * a setenv before you went into the editor and it thinks you're on a dumb
139440Smark  * terminal. Ex treats this like hardcopy and goes into HARDOPEN mode.
140440Smark  * This loses because the first part of vop calls oop in this case.
141440Smark  * The problem is so hard I gave up. I'm not saying it can't be done,
142440Smark  * but I am saying it probably isn't worth the effort.
143440Smark  */
144440Smark 				if (inopen)
145440Smark error("Can't change type of terminal from within open/visual");
146440Smark 				setterm(optname);
147440Smark 			} else {
148440Smark 				CP(op->osvalue, optname);
149440Smark 				op->odefault = 1;
150440Smark 			}
151440Smark 			break;
152440Smark 		}
153440Smark next:
154440Smark 		flush();
155440Smark 	} while (!skipend());
156440Smark 	eol();
157440Smark }
158440Smark 
setend()159440Smark setend()
160440Smark {
161440Smark 
162440Smark 	return (iswhite(peekchar()) || endcmd(peekchar()));
163440Smark }
164440Smark 
prall()165440Smark prall()
166440Smark {
167440Smark 	register int incr = (NOPTS + 2) / 3;
168440Smark 	register int rows = incr;
169440Smark 	register struct option *op = options;
170440Smark 
171440Smark 	for (; rows; rows--, op++) {
172440Smark 		propt(op);
173440Smark 		tab(24);
174440Smark 		propt(&op[incr]);
175440Smark 		if (&op[2*incr] < &options[NOPTS]) {
176440Smark 			tab(56);
177440Smark 			propt(&op[2 * incr]);
178440Smark 		}
179440Smark 		putNFL();
180440Smark 	}
181440Smark }
182440Smark 
propts()183440Smark propts()
184440Smark {
185440Smark 	register struct option *op;
186440Smark 
187440Smark 	for (op = options; op < &options[NOPTS]; op++) {
188440Smark #ifdef V6
189440Smark 		if (op == &options[TERM])
190440Smark #else
191440Smark 		if (op == &options[TTYTYPE])
192440Smark #endif
193440Smark 			continue;
194440Smark 		switch (op->otype) {
195440Smark 
196440Smark 		case ONOFF:
197440Smark 		case NUMERIC:
198440Smark 			if (op->ovalue == op->odefault)
199440Smark 				continue;
200440Smark 			break;
201440Smark 
202440Smark 		case STRING:
203440Smark 			if (op->odefault == 0)
204440Smark 				continue;
205440Smark 			break;
206440Smark 		}
207440Smark 		propt(op);
20830596Sconrad 		ex_putchar(' ');
209440Smark 	}
210440Smark 	noonl();
211440Smark 	flush();
212440Smark }
213440Smark 
propt(op)214440Smark propt(op)
215440Smark 	register struct option *op;
216440Smark {
217440Smark 	register char *name;
218440Smark 
219440Smark 	name = op->oname;
220440Smark 
221440Smark 	switch (op->otype) {
222440Smark 
223440Smark 	case ONOFF:
22430596Sconrad 		ex_printf("%s%s", op->ovalue ? "" : "no", name);
225440Smark 		break;
226440Smark 
227440Smark 	case NUMERIC:
22830596Sconrad 		ex_printf("%s=%d", name, op->ovalue);
229440Smark 		break;
230440Smark 
231440Smark 	case STRING:
232440Smark 	case OTERM:
23330596Sconrad 		ex_printf("%s=%s", name, op->osvalue);
234440Smark 		break;
235440Smark 	}
236440Smark }
237