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