if lisp is set allow `-'s in tagged words (since this is the style);
[unix-history] / usr / src / usr.bin / ex / ex_set.c
CommitLineData
299f2784 1/* Copyright (c) 1981 Regents of the University of California */
e6224cca 2static char *sccsid = "@(#)ex_set.c 7.2 %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;
e6224cca
SL
97 if (value(HARDTABS) <= 0)
98 value(HARDTABS) = TABS;
ff59773d
MH
99 if (op == &options[WINDOW]) {
100 if (value(WINDOW) >= LINES)
101 value(WINDOW) = LINES-1;
887e3e0d 102 vsetsiz(value(WINDOW));
ff59773d 103 }
f3338623
MH
104 break;
105
106 case STRING:
107 case OTERM:
108 cp = optname;
109 while (!setend()) {
110 if (cp >= &optname[ONMSZ])
111 error("String too long@in option assignment");
112 /* adb change: allow whitepace in strings */
113 if( (*cp = getchar()) == '\\')
114 if( peekchar() != EOF)
115 *cp = getchar();
116 cp++;
117 }
118 *cp = 0;
119 if (op->otype == OTERM) {
120/*
121 * At first glance it seems like we shouldn't care if the terminal type
122 * is changed inside visual mode, as long as we assume the screen is
123 * a mess and redraw it. However, it's a much harder problem than that.
124 * If you happen to change from 1 crt to another that both have the same
125 * size screen, it's OK. But if the screen size if different, the stuff
126 * that gets initialized in vop() will be wrong. This could be overcome
127 * by redoing the initialization, e.g. making the first 90% of vop into
128 * a subroutine. However, the most useful case is where you forgot to do
129 * a setenv before you went into the editor and it thinks you're on a dumb
130 * terminal. Ex treats this like hardcopy and goes into HARDOPEN mode.
131 * This loses because the first part of vop calls oop in this case.
132 * The problem is so hard I gave up. I'm not saying it can't be done,
133 * but I am saying it probably isn't worth the effort.
134 */
135 if (inopen)
136error("Can't change type of terminal from within open/visual");
137 setterm(optname);
138 } else {
139 CP(op->osvalue, optname);
140 op->odefault = 1;
141 }
142 break;
143 }
144next:
145 flush();
146 } while (!skipend());
147 eol();
148}
149
150setend()
151{
152
153 return (iswhite(peekchar()) || endcmd(peekchar()));
154}
155
156prall()
157{
158 register int incr = (NOPTS + 2) / 3;
159 register int rows = incr;
160 register struct option *op = options;
161
162 for (; rows; rows--, op++) {
163 propt(op);
164 tab(24);
165 propt(&op[incr]);
166 if (&op[2*incr] < &options[NOPTS]) {
167 tab(56);
168 propt(&op[2 * incr]);
169 }
170 putNFL();
171 }
172}
173
174propts()
175{
176 register struct option *op;
177
178 for (op = options; op < &options[NOPTS]; op++) {
179#ifdef V6
180 if (op == &options[TERM])
181#else
182 if (op == &options[TTYTYPE])
183#endif
184 continue;
185 switch (op->otype) {
186
187 case ONOFF:
188 case NUMERIC:
189 if (op->ovalue == op->odefault)
190 continue;
191 break;
192
193 case STRING:
194 if (op->odefault == 0)
195 continue;
196 break;
197 }
198 propt(op);
199 putchar(' ');
200 }
201 noonl();
202 flush();
203}
204
205propt(op)
206 register struct option *op;
207{
208 register char *name;
209
210 name = op->oname;
211
212 switch (op->otype) {
213
214 case ONOFF:
215 printf("%s%s", op->ovalue ? "" : "no", name);
216 break;
217
218 case NUMERIC:
219 printf("%s=%d", name, op->ovalue);
220 break;
221
222 case STRING:
223 case OTERM:
224 printf("%s=%s", name, op->osvalue);
225 break;
226 }
227}