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