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