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