diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-05-22 11:37:15 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-05-22 11:37:15 +0000 |
commit | 0157a77a51c5e35e093ae03581f66dea010edcc8 (patch) | |
tree | 5e8bd32aa4d2b5ed37b7cf3ad26e8bdfc7f20a04 /usr.bin/vi/common/options_f.c | |
parent | 806021be093ad00ce2022a532c0f4cc99b0065ac (diff) |
new vi
Diffstat (limited to 'usr.bin/vi/common/options_f.c')
-rw-r--r-- | usr.bin/vi/common/options_f.c | 619 |
1 files changed, 234 insertions, 385 deletions
diff --git a/usr.bin/vi/common/options_f.c b/usr.bin/vi/common/options_f.c index bb3cf1b26dc..e45df04a528 100644 --- a/usr.bin/vi/common/options_f.c +++ b/usr.bin/vi/common/options_f.c @@ -1,518 +1,367 @@ /*- * Copyright (c) 1993, 1994 * The Regents of the University of California. All rights reserved. + * Copyright (c) 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * See the LICENSE file for redistribution information. */ +#include "config.h" + #ifndef lint -static char sccsid[] = "@(#)options_f.c 8.36 (Berkeley) 8/17/94"; +static const char sccsid[] = "@(#)options_f.c 10.23 (Berkeley) 5/4/96"; #endif /* not lint */ #include <sys/types.h> #include <sys/queue.h> #include <sys/stat.h> -#include <sys/time.h> #include <bitstring.h> #include <ctype.h> #include <errno.h> #include <limits.h> -#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <termios.h> #include <unistd.h> -#include "compat.h" -#include <db.h> -#include <regex.h> - -#include "vi.h" -#include "../ex/tag.h" - -static int opt_dup __P((SCR *, int, char *)); -static int opt_putenv __P((char *)); +#include "common.h" -#define DECL(f) \ - int \ - f(sp, op, str, val) \ - SCR *sp; \ - OPTION *op; \ - char *str; \ - u_long val; -#define CALL(f) \ - f(sp, op, str, val) - -#define turnoff val - -DECL(f_altwerase) +/* + * PUBLIC: int f_altwerase __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_altwerase(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - if (turnoff) - O_CLR(sp, O_ALTWERASE); - else { - O_SET(sp, O_ALTWERASE); + if (!*valp) O_CLR(sp, O_TTYWERASE); - } return (0); } -DECL(f_cdpath) -{ - return (opt_dup(sp, O_CDPATH, str)); -} - -DECL(f_columns) +/* + * PUBLIC: int f_columns __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_columns(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - char buf[25]; - /* Validate the number. */ - if (val < MINIMUM_SCREEN_COLS) { - msgq(sp, M_ERR, "Screen columns too small, less than %d", + if (*valp < MINIMUM_SCREEN_COLS) { + msgq(sp, M_ERR, "040|Screen columns too small, less than %d", MINIMUM_SCREEN_COLS); return (1); } - /* Set the columns value in the environment for curses. */ - (void)snprintf(buf, sizeof(buf), "COLUMNS=%lu", val); - if (opt_putenv(buf)) - return (1); - - /* This is expensive, don't do it unless it's necessary. */ - if (O_VAL(sp, O_COLUMNS) == val) - return (0); - - /* Set the value. */ - O_VAL(sp, O_COLUMNS) = val; - F_SET(sp, S_RESIZE); - return (0); -} - -DECL(f_leftright) -{ - if (turnoff) - O_CLR(sp, O_LEFTRIGHT); - else - O_SET(sp, O_LEFTRIGHT); - F_SET(sp, S_REFORMAT | S_REDRAW); + /* + * !!! + * It's not uncommon for allocation of huge chunks of memory to cause + * core dumps on various systems. So, we prune out numbers that are + * "obviously" wrong. Vi will not work correctly if it has the wrong + * number of lines/columns for the screen, but at least we don't drop + * core. + */ +#define MAXIMUM_SCREEN_COLS 500 + if (*valp > MAXIMUM_SCREEN_COLS) { + msgq(sp, M_ERR, "041|Screen columns too large, greater than %d", + MAXIMUM_SCREEN_COLS); + return (1); + } return (0); } -DECL(f_lines) +/* + * PUBLIC: int f_lines __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_lines(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - char buf[25]; - /* Validate the number. */ - if (val < MINIMUM_SCREEN_ROWS) { - msgq(sp, M_ERR, "Screen lines too small, less than %d", + if (*valp < MINIMUM_SCREEN_ROWS) { + msgq(sp, M_ERR, "042|Screen lines too small, less than %d", MINIMUM_SCREEN_ROWS); return (1); } - /* Set the rows value in the environment for curses. */ - (void)snprintf(buf, sizeof(buf), "ROWS=%lu", val); - if (opt_putenv(buf)) - return (1); - - /* This is expensive, don't do it unless it's necessary. */ - if (O_VAL(sp, O_LINES) == val) - return (0); - - /* Set the value. */ - O_VAL(sp, O_LINES) = val; - /* - * If no window value set, set a new default window and, - * optionally, a new scroll value. + * !!! + * It's not uncommon for allocation of huge chunks of memory to cause + * core dumps on various systems. So, we prune out numbers that are + * "obviously" wrong. Vi will not work correctly if it has the wrong + * number of lines/columns for the screen, but at least we don't drop + * core. */ - if (!F_ISSET(&sp->opts[O_WINDOW], OPT_SET)) { - O_VAL(sp, O_WINDOW) = val - 1; - if (!F_ISSET(&sp->opts[O_SCROLL], OPT_SET)) - O_VAL(sp, O_SCROLL) = val / 2; - } - - F_SET(sp, S_RESIZE); - return (0); -} - -DECL(f_lisp) -{ - msgq(sp, M_ERR, "The lisp option is not implemented"); - return (0); -} - -DECL(f_list) -{ - if (turnoff) - O_CLR(sp, O_LIST); - else - O_SET(sp, O_LIST); - - F_SET(sp, S_REFORMAT | S_REDRAW); - return (0); -} - -DECL(f_mesg) -{ - struct stat sb; - char *tty; - - /* Find the tty. */ - if ((tty = ttyname(STDERR_FILENO)) == NULL) { - msgq(sp, M_ERR, "ttyname: %s", strerror(errno)); +#define MAXIMUM_SCREEN_ROWS 500 + if (*valp > MAXIMUM_SCREEN_ROWS) { + msgq(sp, M_ERR, "043|Screen lines too large, greater than %d", + MAXIMUM_SCREEN_ROWS); return (1); } - /* Save the tty mode for later; only save it once. */ - if (!F_ISSET(sp->gp, G_SETMODE)) { - F_SET(sp->gp, G_SETMODE); - if (stat(tty, &sb) < 0) { - msgq(sp, M_ERR, "%s: %s", tty, strerror(errno)); - return (1); - } - sp->gp->origmode = sb.st_mode; - } - - if (turnoff) { - if (chmod(tty, sp->gp->origmode & ~S_IWGRP) < 0) { - msgq(sp, M_ERR, "messages not turned off: %s: %s", - tty, strerror(errno)); - return (1); + /* + * Set the value, and the related scroll value. If no window + * value set, set a new default window. + */ + o_set(sp, O_LINES, 0, NULL, *valp); + if (*valp == 1) { + sp->defscroll = 1; + + if (O_VAL(sp, O_WINDOW) == O_D_VAL(sp, O_WINDOW) || + O_VAL(sp, O_WINDOW) > *valp) { + o_set(sp, O_WINDOW, 0, NULL, 1); + o_set(sp, O_WINDOW, OS_DEF, NULL, 1); } - O_CLR(sp, O_MESG); } else { - if (chmod(tty, sp->gp->origmode | S_IWGRP) < 0) { - msgq(sp, M_ERR, "messages not turned on: %s: %s", - tty, strerror(errno)); - return (1); + sp->defscroll = (*valp - 1) / 2; + + if (O_VAL(sp, O_WINDOW) == O_D_VAL(sp, O_WINDOW) || + O_VAL(sp, O_WINDOW) > *valp) { + o_set(sp, O_WINDOW, 0, NULL, *valp - 1); + o_set(sp, O_WINDOW, OS_DEF, NULL, *valp - 1); } - O_SET(sp, O_MESG); } return (0); } /* - * f_modeline -- - * This has been documented in historical systems as both "modeline" - * and as "modelines". Regardless of the name, this option represents - * a security problem of mammoth proportions, not to mention a stunning - * example of what your intro CS professor referred to as the perils of - * mixing code and data. Don't add it, or I will kill you. + * PUBLIC: int f_lisp __P((SCR *, OPTION *, char *, u_long *)); */ -DECL(f_modeline) -{ - if (!turnoff) - msgq(sp, M_ERR, "The modeline(s) option may never be set"); - return (0); -} - -DECL(f_number) +int +f_lisp(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - if (turnoff) - O_CLR(sp, O_NUMBER); - else - O_SET(sp, O_NUMBER); - - F_SET(sp, S_REFORMAT | S_REDRAW); + msgq(sp, M_ERR, "044|The lisp option is not implemented"); return (0); } -DECL(f_octal) +/* + * PUBLIC: int f_msgcat __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_msgcat(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - if (turnoff) - O_CLR(sp, O_OCTAL); - else - O_SET(sp, O_OCTAL); - - key_init(sp); - F_SET(sp, S_REFORMAT | S_REDRAW); + (void)msg_open(sp, str); return (0); } -DECL(f_paragraph) +/* + * PUBLIC: int f_paragraph __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_paragraph(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { if (strlen(str) & 1) { msgq(sp, M_ERR, - "Paragraph options must be in sets of two characters"); + "048|The paragraph option must be in two character groups"); return (1); } - return (opt_dup(sp, O_PARAGRAPHS, str)); -} - -DECL(f_readonly) -{ - if (turnoff) { - O_CLR(sp, O_READONLY); - if (sp->frp != NULL) - F_CLR(sp->frp, FR_RDONLY); - } else { - O_SET(sp, O_READONLY); - if (sp->frp != NULL) - F_SET(sp->frp, FR_RDONLY); - } return (0); } -DECL(f_section) +/* + * PUBLIC: int f_print __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_print(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - if (strlen(str) & 1) { - msgq(sp, M_ERR, - "Section options must be in sets of two characters"); - return (1); - } - return (opt_dup(sp, O_SECTIONS, str)); -} + /* Reinitialize the key fast lookup table. */ + v_key_ilookup(sp); -DECL(f_shiftwidth) -{ - if (val == 0) { - msgq(sp, M_ERR, "The shiftwidth can't be set to 0"); - return (1); - } - O_VAL(sp, O_SHIFTWIDTH) = val; + /* Reformat the screen. */ + F_SET(sp, SC_SCR_REFORMAT); return (0); } /* - * f_sourceany -- - * Historic vi, on startup, source'd $HOME/.exrc and ./.exrc, if they - * were owned by the user. The sourceany option was an undocumented - * feature of historic vi which permitted the startup source'ing of - * .exrc files the user didn't own. This is an obvious security problem, - * and we ignore the option. + * PUBLIC: int f_readonly __P((SCR *, OPTION *, char *, u_long *)); */ -DECL(f_sourceany) +int +f_readonly(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - if (!turnoff) - msgq(sp, M_ERR, "The sourceany option may never be set"); + /* + * !!! + * See the comment in exf.c. + */ + if (*valp) + F_CLR(sp, SC_READONLY); + else + F_SET(sp, SC_READONLY); return (0); } -DECL(f_tabstop) +/* + * PUBLIC: int f_recompile __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_recompile(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - if (val == 0) { - msgq(sp, M_ERR, "Tab stops can't be set to 0"); - return (1); + if (F_ISSET(sp, SC_RE_SEARCH)) { + regfree(&sp->re_c); + F_CLR(sp, SC_RE_SEARCH); } -#define MAXTABSTOP 20 - if (val > MAXTABSTOP) { - msgq(sp, M_ERR, - "Tab stops can't be larger than %d", MAXTABSTOP); - return (1); + if (F_ISSET(sp, SC_RE_SUBST)) { + regfree(&sp->subre_c); + F_CLR(sp, SC_RE_SUBST); } - O_VAL(sp, O_TABSTOP) = val; - - F_SET(sp, S_REFORMAT | S_REDRAW); return (0); } -DECL(f_tags) -{ - return (opt_dup(sp, O_TAGS, str)); -} - -DECL(f_term) +/* + * PUBLIC: int f_reformat __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_reformat(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - char buf[256]; - - if (opt_dup(sp, O_TERM, str)) - return (1); - - /* Set the terminal value in the environment for curses. */ - (void)snprintf(buf, sizeof(buf), "TERM=%s", str); - if (opt_putenv(buf)) - return (1); + F_SET(sp, SC_SCR_REFORMAT); return (0); } -DECL(f_ttywerase) +/* + * PUBLIC: int f_section __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_section(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - if (turnoff) - O_CLR(sp, O_TTYWERASE); - else { - O_SET(sp, O_TTYWERASE); - O_CLR(sp, O_ALTWERASE); + if (strlen(str) & 1) { + msgq(sp, M_ERR, + "049|The section option must be in two character groups"); + return (1); } return (0); } -DECL(f_w300) +/* + * PUBLIC: int f_ttywerase __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_ttywerase(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - /* Historical behavior for w300 was < 1200. */ - if (baud_from_bval(sp) >= 1200) - return (0); - - if (CALL(f_window)) - return (1); - - if (val > O_VAL(sp, O_LINES) - 1) - val = O_VAL(sp, O_LINES) - 1; - O_VAL(sp, O_W300) = val; + if (!*valp) + O_CLR(sp, O_ALTWERASE); return (0); } -DECL(f_w1200) +/* + * PUBLIC: int f_w300 __P((SCR *, OPTION *, char *, u_long *)); + */ +int +f_w300(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { u_long v; - /* Historical behavior for w1200 was == 1200. */ - v = baud_from_bval(sp); - if (v < 1200 || v > 4800) - return (0); - - if (CALL(f_window)) + /* Historical behavior for w300 was < 1200. */ + if (sp->gp->scr_baud(sp, &v)) return (1); - - if (val > O_VAL(sp, O_LINES) - 1) - val = O_VAL(sp, O_LINES) - 1; - O_VAL(sp, O_W1200) = val; - return (0); -} - -DECL(f_w9600) -{ - speed_t v; - - /* Historical behavior for w9600 was > 1200. */ - v = baud_from_bval(sp); - if (v <= 4800) + if (v >= 1200) return (0); - if (CALL(f_window)) - return (1); - - if (val > O_VAL(sp, O_LINES) - 1) - val = O_VAL(sp, O_LINES) - 1; - O_VAL(sp, O_W9600) = val; - return (0); -} - -DECL(f_window) -{ - if (val < MINIMUM_SCREEN_ROWS) { - msgq(sp, M_ERR, "Window too small, less than %d", - MINIMUM_SCREEN_ROWS); - return (1); - } - if (val > O_VAL(sp, O_LINES) - 1) - val = O_VAL(sp, O_LINES) - 1; - O_VAL(sp, O_WINDOW) = val; - O_VAL(sp, O_SCROLL) = val / 2; - - return (0); + return (f_window(sp, op, str, valp)); } /* - * opt_dup -- - * Copy a string value for user display. + * PUBLIC: int f_w1200 __P((SCR *, OPTION *, char *, u_long *)); */ -static int -opt_dup(sp, opt, str) +int +f_w1200(sp, op, str, valp) SCR *sp; - int opt; + OPTION *op; char *str; + u_long *valp; { - char *p; + u_long v; - /* Copy for user display. */ - if ((p = strdup(str)) == NULL) { - msgq(sp, M_SYSERR, NULL); + /* Historical behavior for w1200 was == 1200. */ + if (sp->gp->scr_baud(sp, &v)) return (1); - } - - /* Free the old contents. */ - if (F_ISSET(&sp->opts[opt], OPT_ALLOCATED)) - free(O_STR(sp, opt)); - - /* Note that it's set and allocated. */ - F_SET(&sp->opts[opt], OPT_ALLOCATED | OPT_SET); + if (v < 1200 || v > 4800) + return (0); - /* Assign new contents. */ - O_STR(sp, opt) = p; - return (0); + return (f_window(sp, op, str, valp)); } /* - * opt_putenv -- - * Put a value into the environment. We use putenv(3) because it's - * more portable. The following hack is because some moron decided - * to keep a reference to the memory passed to putenv(3), instead of - * having it allocate its own. Someone clearly needs to get promoted - * into management. + * PUBLIC: int f_w9600 __P((SCR *, OPTION *, char *, u_long *)); */ -static int -opt_putenv(s) - char *s; +int +f_w9600(sp, op, str, valp) + SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - char *t; + u_long v; - /* - * XXX - * Memory leak. - */ - if ((t = strdup(s)) == NULL) + /* Historical behavior for w9600 was > 1200. */ + if (sp->gp->scr_baud(sp, &v)) return (1); - return (putenv(t)); + if (v <= 4800) + return (0); + + return (f_window(sp, op, str, valp)); } /* - * baud_from_bval -- - * Return the baud rate using the standard defines. + * PUBLIC: int f_window __P((SCR *, OPTION *, char *, u_long *)); */ -u_long -baud_from_bval(sp) +int +f_window(sp, op, str, valp) SCR *sp; + OPTION *op; + char *str; + u_long *valp; { - if (!F_ISSET(sp->gp, G_TERMIOS_SET)) - return (9600); - - /* - * XXX - * There's no portable way to get a "baud rate" -- cfgetospeed(3) - * returns the value associated with some #define, which we may - * never have heard of, or which may be a purely local speed. Vi - * only cares if it's SLOW (w300), slow (w1200) or fast (w9600). - * Try and detect the slow ones, and default to fast. - */ - switch (cfgetospeed(&sp->gp->original_termios)) { - case B50: - case B75: - case B110: - case B134: - case B150: - case B200: - case B300: - case B600: - return (600); - case B1200: - return (1200); - } - return (9600); + if (*valp >= O_VAL(sp, O_LINES) - 1 && + (*valp = O_VAL(sp, O_LINES) - 1) == 0) + *valp = 1; + return (0); } |