make cut buffer displays interruptible
[nvi.git] / common / options_f.c
blobdfde38ba7f3eedc8890add92581107e051c2139a
1 /*-
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
6 */
8 #ifndef lint
9 static char sccsid[] = "$Id: options_f.c,v 8.25 1993/12/20 16:58:24 bostic Exp $ (Berkeley) $Date: 1993/12/20 16:58:24 $";
10 #endif /* not lint */
12 #include <sys/types.h>
13 #include <sys/stat.h>
15 #include <ctype.h>
16 #include <errno.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
21 #include "vi.h"
22 #include "tag.h"
24 static int opt_putenv __P((char *));
26 #define DECL(f) \
27 int \
28 f(sp, op, str, val) \
29 SCR *sp; \
30 OPTION *op; \
31 char *str; \
32 u_long val;
33 #define CALL(f) \
34 f(sp, op, str, val)
36 #define turnoff val
38 DECL(f_altwerase)
40 if (turnoff)
41 O_CLR(sp, O_ALTWERASE);
42 else {
43 O_SET(sp, O_ALTWERASE);
44 O_CLR(sp, O_TTYWERASE);
46 return (0);
49 DECL(f_ttywerase)
51 if (turnoff)
52 O_CLR(sp, O_TTYWERASE);
53 else {
54 O_SET(sp, O_TTYWERASE);
55 O_CLR(sp, O_ALTWERASE);
57 return (0);
60 DECL(f_columns)
62 char buf[25];
64 /* Validate the number. */
65 if (val < MINIMUM_SCREEN_COLS) {
66 msgq(sp, M_ERR, "Screen columns too small, less than %d.",
67 MINIMUM_SCREEN_COLS);
68 return (1);
70 if (val < O_VAL(sp, O_SHIFTWIDTH)) {
71 msgq(sp, M_ERR,
72 "Screen columns too small, less than shiftwidth.");
73 return (1);
75 if (val < O_VAL(sp, O_SIDESCROLL)) {
76 msgq(sp, M_ERR,
77 "Screen columns too small, less than sidescroll.");
78 return (1);
80 if (val < O_VAL(sp, O_TABSTOP)) {
81 msgq(sp, M_ERR,
82 "Screen columns too small, less than tabstop.");
83 return (1);
85 if (val < O_VAL(sp, O_WRAPMARGIN)) {
86 msgq(sp, M_ERR,
87 "Screen columns too small, less than wrapmargin.");
88 return (1);
90 #ifdef XXX_NOT_RIGHT
92 * This has to be checked by reaching down into the screen code.
94 if (val < O_NUMBER_LENGTH) {
95 msgq(sp, M_ERR,
96 "Screen columns too small, less than number option.");
97 return (1);
99 #endif
100 /* Set the columns value in the environment for curses. */
101 (void)snprintf(buf, sizeof(buf), "COLUMNS=%lu", val);
102 if (opt_putenv(buf))
103 return (1);
105 /* This is expensive, don't do it unless it's necessary. */
106 if (O_VAL(sp, O_COLUMNS) == val)
107 return (0);
109 /* Set the value. */
110 O_VAL(sp, O_COLUMNS) = val;
112 F_SET(sp, S_RESIZE);
113 return (0);
116 DECL(f_keytime)
118 O_VAL(sp, O_KEYTIME) = val;
119 return (0);
122 DECL(f_leftright)
124 if (turnoff)
125 O_CLR(sp, O_LEFTRIGHT);
126 else
127 O_SET(sp, O_LEFTRIGHT);
128 F_SET(sp, S_REFORMAT | S_REDRAW);
129 return (0);
132 DECL(f_lines)
134 char buf[25];
136 /* Validate the number. */
137 if (val < MINIMUM_SCREEN_ROWS) {
138 msgq(sp, M_ERR, "Screen lines too small, less than %d.",
139 MINIMUM_SCREEN_ROWS);
140 return (1);
143 /* Set the rows value in the environment for curses. */
144 (void)snprintf(buf, sizeof(buf), "ROWS=%lu", val);
145 if (opt_putenv(buf))
146 return (1);
148 /* This is expensive, don't do it unless it's necessary. */
149 if (O_VAL(sp, O_LINES) == val)
150 return (0);
152 /* Set the value. */
153 O_VAL(sp, O_LINES) = val;
156 * If no window value set, set a new default window and,
157 * optionally, a new scroll value.
159 if (!F_ISSET(&sp->opts[O_WINDOW], OPT_SET)) {
160 O_VAL(sp, O_WINDOW) = val - 1;
161 if (!F_ISSET(&sp->opts[O_SCROLL], OPT_SET))
162 O_VAL(sp, O_SCROLL) = val / 2;
165 F_SET(sp, S_RESIZE);
166 return (0);
169 DECL(f_lisp)
171 msgq(sp, M_ERR, "The lisp option is not implemented.");
172 return (0);
175 DECL(f_list)
177 if (turnoff)
178 O_CLR(sp, O_LIST);
179 else
180 O_SET(sp, O_LIST);
182 F_SET(sp, S_REFORMAT | S_REDRAW);
183 return (0);
186 DECL(f_matchtime)
188 O_VAL(sp, O_MATCHTIME) = val;
189 return (0);
192 DECL(f_mesg)
194 struct stat sb;
195 char *tty;
197 /* Find the tty. */
198 if ((tty = ttyname(STDERR_FILENO)) == NULL) {
199 msgq(sp, M_ERR, "ttyname: %s.", strerror(errno));
200 return (1);
203 /* Save the tty mode for later; only save it once. */
204 if (!F_ISSET(sp->gp, G_SETMODE)) {
205 F_SET(sp->gp, G_SETMODE);
206 if (stat(tty, &sb) < 0) {
207 msgq(sp, M_ERR, "%s: %s.", tty, strerror(errno));
208 return (1);
210 sp->gp->origmode = sb.st_mode;
213 if (turnoff) {
214 if (chmod(tty, sp->gp->origmode & ~S_IWGRP) < 0) {
215 msgq(sp, M_ERR, "messages not turned off: %s: %s.",
216 tty, strerror(errno));
217 return (1);
219 O_CLR(sp, O_MESG);
220 } else {
221 if (chmod(tty, sp->gp->origmode | S_IWGRP) < 0) {
222 msgq(sp, M_ERR, "messages not turned on: %s: %s.",
223 tty, strerror(errno));
224 return (1);
226 O_SET(sp, O_MESG);
228 return (0);
232 * f_modeline --
233 * This has been documented in historical systems as both "modeline"
234 * and as "modelines". Regardless of the name, this option represents
235 * a security problem of mammoth proportions, not to mention a stunning
236 * example of what your intro CS professor referred to as the perils of
237 * mixing code and data. Don't add it, or I will kill you.
239 DECL(f_modeline)
241 if (!turnoff)
242 msgq(sp, M_ERR, "The modeline(s) option may never be set.");
243 return (0);
246 DECL(f_number)
248 if (turnoff)
249 O_CLR(sp, O_NUMBER);
250 else
251 O_SET(sp, O_NUMBER);
253 F_SET(sp, S_REFORMAT | S_REDRAW);
254 return (0);
257 DECL(f_optimize)
259 msgq(sp, M_ERR, "The optimize option is not implemented.");
260 return (0);
263 DECL(f_paragraph)
265 if (strlen(str) & 1) {
266 msgq(sp, M_ERR,
267 "Paragraph options must be in sets of two characters.");
268 return (1);
271 if (F_ISSET(&sp->opts[O_PARAGRAPHS], OPT_ALLOCATED))
272 free(O_STR(sp, O_PARAGRAPHS));
273 if ((O_STR(sp, O_PARAGRAPHS) = strdup(str)) == NULL) {
274 msgq(sp, M_SYSERR, NULL);
275 return (1);
277 F_SET(&sp->opts[O_PARAGRAPHS], OPT_ALLOCATED | OPT_SET);
278 return (0);
281 DECL(f_readonly)
283 if (turnoff) {
284 O_CLR(sp, O_READONLY);
285 if (sp->frp != NULL)
286 F_CLR(sp->frp, FR_RDONLY);
287 } else {
288 O_SET(sp, O_READONLY);
289 if (sp->frp != NULL)
290 F_SET(sp->frp, FR_RDONLY);
292 return (0);
295 DECL(f_ruler)
297 if (turnoff)
298 O_CLR(sp, O_RULER);
299 else
300 O_SET(sp, O_RULER);
301 return (0);
304 DECL(f_section)
306 if (strlen(str) & 1) {
307 msgq(sp, M_ERR,
308 "Section options must be in sets of two characters.");
309 return (1);
312 if (F_ISSET(&sp->opts[O_SECTIONS], OPT_ALLOCATED))
313 free(O_STR(sp, O_SECTIONS));
314 if ((O_STR(sp, O_SECTIONS) = strdup(str)) == NULL) {
315 msgq(sp, M_SYSERR, NULL);
316 return (1);
318 F_SET(&sp->opts[O_SECTIONS], OPT_ALLOCATED | OPT_SET);
319 return (0);
322 DECL(f_shiftwidth)
324 if (val == 0) {
325 msgq(sp, M_ERR, "The shiftwidth can't be set to 0.");
326 return (1);
328 if (val > O_VAL(sp, O_COLUMNS)) {
329 msgq(sp, M_ERR,
330 "Shiftwidth can't be larger than screen size.");
331 return (1);
333 O_VAL(sp, O_SHIFTWIDTH) = val;
334 return (0);
337 DECL(f_sidescroll)
339 if (val > O_VAL(sp, O_COLUMNS)) {
340 msgq(sp, M_ERR,
341 "Sidescroll can't be larger than screen size.");
342 return (1);
344 O_VAL(sp, O_SIDESCROLL) = val;
345 return (0);
349 * f_sourceany --
350 * Historic vi, on startup, source'd $HOME/.exrc and ./.exrc, if they
351 * were owned by the user. The sourceany option was an undocumented
352 * feature of historic vi which permitted the startup source'ing of
353 * .exrc files the user didn't own. This is an obvious security problem,
354 * and we ignore the option.
356 DECL(f_sourceany)
358 if (!turnoff)
359 msgq(sp, M_ERR, "The sourceany option may never be set.");
360 return (0);
363 DECL(f_tabstop)
365 if (val == 0) {
366 msgq(sp, M_ERR, "Tab stops can't be set to 0.");
367 return (1);
369 #define MAXTABSTOP 20
370 if (val > MAXTABSTOP) {
371 msgq(sp, M_ERR,
372 "Tab stops can't be larger than %d.", MAXTABSTOP);
373 return (1);
375 if (val > O_VAL(sp, O_COLUMNS)) {
376 msgq(sp, M_ERR,
377 "Tab stops can't be larger than screen size.",
378 MAXTABSTOP);
379 return (1);
381 O_VAL(sp, O_TABSTOP) = val;
383 F_SET(sp, S_REFORMAT | S_REDRAW);
384 return (0);
387 DECL(f_tags)
389 char *p;
391 /* Copy for user display. */
392 p = O_STR(sp, O_TAGS);
393 if ((O_STR(sp, O_TAGS) = strdup(str)) == NULL) {
394 O_STR(sp, O_TAGS) = p;
395 msgq(sp, M_SYSERR, NULL);
396 return (1);
398 if (F_ISSET(&sp->opts[O_TAGS], OPT_ALLOCATED))
399 FREE(p, strlen(p) + 1);
400 F_SET(&sp->opts[O_TAGS], OPT_ALLOCATED | OPT_SET);
401 return (0);
404 DECL(f_term)
406 char buf[256];
408 if (F_ISSET(&sp->opts[O_TERM], OPT_ALLOCATED))
409 free(O_STR(sp, O_TERM));
410 if ((O_STR(sp, O_TERM) = strdup(str)) == NULL) {
411 msgq(sp, M_SYSERR, NULL);
412 return (1);
414 F_SET(&sp->opts[O_TERM], OPT_ALLOCATED | OPT_SET);
416 /* Set the terminal value in the environment for curses. */
417 (void)snprintf(buf, sizeof(buf), "TERM=%s", str);
418 if (opt_putenv(buf))
419 return (1);
421 if (set_window_size(sp, 0, 0))
422 return (1);
423 return (0);
426 DECL(f_w300)
428 /* Historical behavior for w300 was < 1200. */
429 if (baud_from_bval(sp) >= 1200)
430 return (0);
432 if (CALL(f_window))
433 return (1);
435 if (val > O_VAL(sp, O_LINES) - 1)
436 val = O_VAL(sp, O_LINES) - 1;
437 O_VAL(sp, O_W300) = val;
438 return (0);
441 DECL(f_w1200)
443 u_long v;
445 /* Historical behavior for w1200 was == 1200. */
446 v = baud_from_bval(sp);
447 if (v < 1200 || v > 4800)
448 return (0);
450 if (CALL(f_window))
451 return (1);
453 if (val > O_VAL(sp, O_LINES) - 1)
454 val = O_VAL(sp, O_LINES) - 1;
455 O_VAL(sp, O_W1200) = val;
456 return (0);
459 DECL(f_w9600)
461 speed_t v;
463 /* Historical behavior for w9600 was > 1200. */
464 v = baud_from_bval(sp);
465 if (v <= 4800)
466 return (0);
468 if (CALL(f_window))
469 return (1);
471 if (val > O_VAL(sp, O_LINES) - 1)
472 val = O_VAL(sp, O_LINES) - 1;
473 O_VAL(sp, O_W9600) = val;
474 return (0);
477 DECL(f_window)
479 if (val < MINIMUM_SCREEN_ROWS) {
480 msgq(sp, M_ERR, "Window too small, less than %d.",
481 MINIMUM_SCREEN_ROWS);
482 return (1);
484 if (val > O_VAL(sp, O_LINES) - 1)
485 val = O_VAL(sp, O_LINES) - 1;
486 O_VAL(sp, O_WINDOW) = val;
487 O_VAL(sp, O_SCROLL) = val / 2;
489 return (0);
492 DECL(f_wrapmargin)
494 if (val > O_VAL(sp, O_COLUMNS)) {
495 msgq(sp, M_ERR,
496 "Wrapmargin value can't be larger than screen size.");
497 return (1);
499 O_VAL(sp, O_WRAPMARGIN) = val;
500 return (0);
504 * opt_putenv --
505 * Put a value into the environment. We use putenv(3) because it's
506 * more portable. The following hack is because some moron decided
507 * to keep a reference to the memory passed to putenv(3), instead of
508 * having it allocate its own. Someone clearly needs to get promoted
509 * into management.
511 static int
512 opt_putenv(s)
513 char *s;
515 char *t;
517 /* Memory leak. */
518 if ((t = strdup(s)) == NULL)
519 return (1);
520 return (putenv(t));