Commit | Line | Data |
---|---|---|
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 | 9 | static 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 | */ | |
19 | char optname[ONMSZ]; | |
20 | ||
21 | set() | |
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) { | |
58 | dontset: | |
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(); | |
81 | printone: | |
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) | |
145 | error("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 | } | |
153 | next: | |
154 | flush(); | |
155 | } while (!skipend()); | |
156 | eol(); | |
157 | } | |
158 | ||
159 | setend() | |
160 | { | |
161 | ||
162 | return (iswhite(peekchar()) || endcmd(peekchar())); | |
163 | } | |
164 | ||
165 | prall() | |
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 | ||
183 | propts() | |
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 | ||
214 | propt(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 | } |