1 /*-
2  * Copyright (c) 2002 Jordan DeLong
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the author nor the names of contributors may be
14  *    used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 #include "editor.h"
30 
31 options_t	options;
32 optlist_t	*options_hash;
33 
options_init()34 void options_init() {
35 	options_hash = hash_alloc("options_hash", OPTIONS_BUCKETS,
36 		offsetof(opt_t, o_list));
37 
38 	options_add("autoviews", OPT_STRING, &options.autoviews, 0);
39 	options_add("tabwidth", OPT_UINT, &options.tabwidth, 1);
40 	options_add("killringmax", OPT_UINT, &options.killringmax, 0);
41 	options_add("markringmax", OPT_UINT, &options.markringmax, 0);
42 	options_add("stickyhomekey", OPT_BOOL, &options.stickyhomekey, 1);
43 	options_add("chunkyscroll", OPT_BOOL, &options.chunkyscroll, 1);
44 	options_add("noexplicitmark", OPT_BOOL, &options.noexplicitmark, 1);
45 	options_add("highbitmeta", OPT_BOOL, &options.highbitmeta, 1);
46 	options_add("icasesearch", OPT_BOOL, &options.icasesearch, 1);
47 	options_add("autoindent", OPT_BOOL, &options.autoindent, 1);
48 	options_add("parenflash", OPT_BOOL, &options.parenflash, 1);
49 	options_add("forcefilenl", OPT_BOOL, &options.forcefilenl, 1);
50 	options_add("printnlatend", OPT_BOOL, &options.printnlatend, 0);
51 	options_add("intrchar", OPT_CHAR, &options.intrchar, 0);
52 	options_add("blanklinechar", OPT_CHAR, &options.blanklinechar, 0);
53 
54 	/* set default values for options */
55 	options.autoviews = NULL;
56 	options.tabwidth = 8;
57 	options.killringmax = 60;
58 	options.markringmax = 16;
59 	options.stickyhomekey = 1;
60 	options.chunkyscroll = 1;
61 	options.noexplicitmark = 1;
62 	options.highbitmeta = 0;
63 	options.icasesearch = 0;
64 	options.autoindent = 1;
65 	options.parenflash = 1;
66 	options.forcefilenl = 0;
67 	options.printnlatend = 0;
68 	options.intrchar = '\003';		/* Control-C */
69 	options.blanklinechar = '~';
70 }
71 
delopt(opt_t * opt)72 static void delopt(opt_t *opt) {
73 	u_char *s;
74 
75 	LIST_REMOVE(opt, o_list);
76 	if (opt->type == OPT_STRING) {
77 		s = *((u_char **) opt->val);
78 		if (s)
79 			free(s);
80 	}
81 	free(opt->name);
82 	free(opt);
83 }
84 
options_shutdown()85 void options_shutdown() {
86 	int idx;
87 
88 	for (idx = 0; idx < OPTIONS_BUCKETS; idx++)
89 		while (!LIST_EMPTY(&options_hash[idx]))
90 			delopt(LIST_FIRST(&options_hash[idx]));
91 	hash_free(options_hash);
92 }
93 
options_add(u_char * name,int type,void * var,int setable)94 void options_add(u_char *name, int type, void *var, int setable) {
95 	opt_t *opt;
96 	int idx;
97 
98 	opt = ckmalloc(sizeof(opt_t));
99 	opt->type = type;
100 	opt->name = ckstrdup(name);
101 	opt->val = var;
102 	opt->setable = setable;
103 	idx = hash_string(OPTIONS_BUCKETS, name);
104 	LIST_INSERT_HEAD(&options_hash[idx], opt, o_list);
105 }
106 
options_rm(u_char * name)107 void options_rm(u_char *name) {
108 	opt_t *opt;
109 
110 	opt = options_lookup(name);
111 	if (opt)
112 		delopt(opt);
113 }
114 
options_lookup(u_char * name)115 opt_t *options_lookup(u_char *name) {
116 	opt_t *opt;
117 	int idx;
118 
119 	idx = hash_string(OPTIONS_BUCKETS, name);
120 	LIST_FOREACH(opt, &options_hash[idx], o_list)
121 		if (!strcmp(opt->name, name))
122 			return opt;
123 
124 	return NULL;
125 }
126 
options_set(opt_t * opt,u_char * strval)127 void options_set(opt_t *opt, u_char *strval) {
128 	u_char **s, *vis;
129 	int i;
130 
131 	switch (opt->type) {
132 	case OPT_INT:
133 		*((int *) opt->val) = atoi(strval);
134 		break;
135 	case OPT_UINT:
136 		i = atoi(strval);
137 		if (i < 0)
138 			i = 0;
139 		*((u_int *) opt->val) = i;
140 		break;
141 	case OPT_BOOL:
142 		if (tolower(strval[0] == 't') || strval[0] == '1')
143 			i = 1;
144 		else
145 			i = 0;
146 		*((u_int *) opt->val) = i;
147 		break;
148 	case OPT_CHAR:
149 		vis = ckmalloc(strlen(strval) + 1);
150 		if (strunvis(vis, strval) != -1)
151 			*((u_char *) opt->val) = vis[0];
152 		free(vis);
153 		break;
154 	case OPT_STRING:
155 		s = (u_char **) opt->val;
156 		if (*s)
157 			free(*s);
158 		*s = ckstrdup(strval);
159 		break;
160 	case OPT_COLOR:
161 		if ((i = color_lookup(strval)) != COLOR_NULL)
162 			*((int *) opt->val) = i;
163 		break;
164 	case OPT_CALL: {
165 		void (*f)(u_char *);
166 		f = opt->val;
167 		f(strval);
168 		break;
169 	}
170 	default:
171 		assert(0);
172 	}
173 }
174