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