1/*-
2 * Copyright (c) 1993, 1994
3 *	The Regents of the University of California.  All rights reserved.
4 * Copyright (c) 1993, 1994, 1995, 1996
5 *	Keith Bostic.  All rights reserved.
6 *
7 * See the LICENSE file for redistribution information.
8 */
9
10#include "config.h"
11
12#include <sys/types.h>
13#include <sys/queue.h>
14#include <sys/stat.h>
15
16#include <bitstring.h>
17#include <ctype.h>
18#include <errno.h>
19#include <limits.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
24
25#include "common.h"
26
27/*
28 * PUBLIC: int f_altwerase(SCR *, OPTION *, char *, u_long *);
29 */
30int
31f_altwerase(SCR *sp, OPTION *op, char *str, u_long *valp)
32{
33	if (*valp)
34		O_CLR(sp, O_TTYWERASE);
35	return (0);
36}
37
38/*
39 * PUBLIC: int f_columns(SCR *, OPTION *, char *, u_long *);
40 */
41int
42f_columns(SCR *sp, OPTION *op, char *str, u_long *valp)
43{
44	/* Validate the number. */
45	if (*valp < MINIMUM_SCREEN_COLS) {
46		msgq(sp, M_ERR, "040|Screen columns too small, less than %d",
47		    MINIMUM_SCREEN_COLS);
48		return (1);
49	}
50
51	/*
52	 * !!!
53	 * It's not uncommon for allocation of huge chunks of memory to cause
54	 * core dumps on various systems.  So, we prune out numbers that are
55	 * "obviously" wrong.  Vi will not work correctly if it has the wrong
56	 * number of lines/columns for the screen, but at least we don't drop
57	 * core.
58	 */
59#define	MAXIMUM_SCREEN_COLS	500
60	if (*valp > MAXIMUM_SCREEN_COLS) {
61		msgq(sp, M_ERR, "041|Screen columns too large, greater than %d",
62		    MAXIMUM_SCREEN_COLS);
63		return (1);
64	}
65	return (0);
66}
67
68/*
69 * PUBLIC: int f_lines(SCR *, OPTION *, char *, u_long *);
70 */
71int
72f_lines(SCR *sp, OPTION *op, char *str, u_long *valp)
73{
74	/* Validate the number. */
75	if (*valp < MINIMUM_SCREEN_ROWS) {
76		msgq(sp, M_ERR, "042|Screen lines too small, less than %d",
77		    MINIMUM_SCREEN_ROWS);
78		return (1);
79	}
80
81	/*
82	 * !!!
83	 * It's not uncommon for allocation of huge chunks of memory to cause
84	 * core dumps on various systems.  So, we prune out numbers that are
85	 * "obviously" wrong.  Vi will not work correctly if it has the wrong
86	 * number of lines/columns for the screen, but at least we don't drop
87	 * core.
88	 */
89#define	MAXIMUM_SCREEN_ROWS	500
90	if (*valp > MAXIMUM_SCREEN_ROWS) {
91		msgq(sp, M_ERR, "043|Screen lines too large, greater than %d",
92		    MAXIMUM_SCREEN_ROWS);
93		return (1);
94	}
95
96	/*
97	 * Set the value, and the related scroll value.  If no window
98	 * value set, set a new default window.
99	 */
100	o_set(sp, O_LINES, 0, NULL, *valp);
101	if (*valp == 1) {
102		sp->defscroll = 1;
103
104		if (O_VAL(sp, O_WINDOW) == O_D_VAL(sp, O_WINDOW) ||
105		    O_VAL(sp, O_WINDOW) > *valp) {
106			o_set(sp, O_WINDOW, 0, NULL, 1);
107			o_set(sp, O_WINDOW, OS_DEF, NULL, 1);
108		}
109	} else {
110		sp->defscroll = (*valp - 1) / 2;
111
112		if (O_VAL(sp, O_WINDOW) == O_D_VAL(sp, O_WINDOW) ||
113		    O_VAL(sp, O_WINDOW) > *valp) {
114			o_set(sp, O_WINDOW, 0, NULL, *valp - 1);
115			o_set(sp, O_WINDOW, OS_DEF, NULL, *valp - 1);
116		}
117	}
118	return (0);
119}
120
121/*
122 * PUBLIC: int f_lisp(SCR *, OPTION *, char *, u_long *);
123 */
124int
125f_lisp(SCR *sp, OPTION *op, char *str, u_long *valp)
126{
127	msgq(sp, M_ERR, "044|The lisp option is not implemented");
128	return (0);
129}
130
131/*
132 * PUBLIC: int f_msgcat(SCR *, OPTION *, char *, u_long *);
133 */
134int
135f_msgcat(SCR *sp, OPTION *op, char *str, u_long *valp)
136{
137	(void)msg_open(sp, str);
138	return (0);
139}
140
141/*
142 * PUBLIC: int f_print(SCR *, OPTION *, char *, u_long *);
143 */
144int
145f_print(SCR *sp, OPTION *op, char *str, u_long *valp)
146{
147	int offset = op - sp->opts;
148
149	/* Preset the value, needed for reinitialization of lookup table. */
150	if (offset == O_OCTAL || offset == O_ALTNOTATION) {
151		if (*valp)
152			O_SET(sp, offset);
153		else
154			O_CLR(sp, offset);
155	} else if (o_set(sp, offset, OS_STRDUP, str, 0))
156		return(1);
157
158	/* Reinitialize the key fast lookup table. */
159	v_key_ilookup(sp);
160
161	/* Reformat the screen. */
162	F_SET(sp, SC_SCR_REFORMAT);
163	return (0);
164}
165
166/*
167 * PUBLIC: int f_readonly(SCR *, OPTION *, char *, u_long *);
168 */
169int
170f_readonly(SCR *sp, OPTION *op, char *str, u_long *valp)
171{
172	/*
173	 * !!!
174	 * See the comment in exf.c.
175	 */
176	if (*valp)
177		F_SET(sp, SC_READONLY);
178	else
179		F_CLR(sp, SC_READONLY);
180	return (0);
181}
182
183/*
184 * PUBLIC: int f_recompile(SCR *, OPTION *, char *, u_long *);
185 */
186int
187f_recompile(SCR *sp, OPTION *op, char *str, u_long *valp)
188{
189	if (F_ISSET(sp, SC_RE_SEARCH)) {
190		regfree(&sp->re_c);
191		F_CLR(sp, SC_RE_SEARCH);
192	}
193	if (F_ISSET(sp, SC_RE_SUBST)) {
194		regfree(&sp->subre_c);
195		F_CLR(sp, SC_RE_SUBST);
196	}
197	return (0);
198}
199
200/*
201 * PUBLIC: int f_reformat(SCR *, OPTION *, char *, u_long *);
202 */
203int
204f_reformat(SCR *sp, OPTION *op, char *str, u_long *valp)
205{
206	F_SET(sp, SC_SCR_REFORMAT);
207	return (0);
208}
209
210/*
211 * PUBLIC: int f_ttywerase(SCR *, OPTION *, char *, u_long *);
212 */
213int
214f_ttywerase(SCR *sp, OPTION *op, char *str, u_long *valp)
215{
216	if (*valp)
217		O_CLR(sp, O_ALTWERASE);
218	return (0);
219}
220
221/*
222 * PUBLIC: int f_w300(SCR *, OPTION *, char *, u_long *);
223 */
224int
225f_w300(SCR *sp, OPTION *op, char *str, u_long *valp)
226{
227	u_long v;
228
229	/* Historical behavior for w300 was < 1200. */
230	if (sp->gp->scr_baud(sp, &v))
231		return (1);
232	if (v >= 1200)
233		return (0);
234
235	return (f_window(sp, op, str, valp));
236}
237
238/*
239 * PUBLIC: int f_w1200(SCR *, OPTION *, char *, u_long *);
240 */
241int
242f_w1200(SCR *sp, OPTION *op, char *str, u_long *valp)
243{
244	u_long v;
245
246	/* Historical behavior for w1200 was == 1200. */
247	if (sp->gp->scr_baud(sp, &v))
248		return (1);
249	if (v < 1200 || v > 4800)
250		return (0);
251
252	return (f_window(sp, op, str, valp));
253}
254
255/*
256 * PUBLIC: int f_w9600(SCR *, OPTION *, char *, u_long *);
257 */
258int
259f_w9600(SCR *sp, OPTION *op, char *str, u_long *valp)
260{
261	u_long v;
262
263	/* Historical behavior for w9600 was > 1200. */
264	if (sp->gp->scr_baud(sp, &v))
265		return (1);
266	if (v <= 4800)
267		return (0);
268
269	return (f_window(sp, op, str, valp));
270}
271
272/*
273 * PUBLIC: int f_window(SCR *, OPTION *, char *, u_long *);
274 */
275int
276f_window(SCR *sp, OPTION *op, char *str, u_long *valp)
277{
278	if (*valp >= O_VAL(sp, O_LINES) - 1 &&
279	    (*valp = O_VAL(sp, O_LINES) - 1) == 0)
280		*valp = 1;
281	return (0);
282}
283
284/*
285 * PUBLIC: int f_encoding(SCR *, OPTION *, char *, u_long *);
286 */
287int
288f_encoding(SCR *sp, OPTION *op, char *str, u_long *valp)
289{
290	int offset = op - sp->opts;
291
292	return conv_enc(sp, offset, str);
293}
294