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