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