BZ_bzRead2 is based on BZ_bzRead from the bzlib library.
[elinks.git] / src / config / options.h
blob77e2a1572a9c54e7a9dce0d6735553be49c512ad
2 #ifndef EL__CONFIG_OPTIONS_H
3 #define EL__CONFIG_OPTIONS_H
5 #include "main/object.h"
6 #include "util/color.h"
7 #include "util/lists.h"
8 #include "util/memory.h"
9 #include "util/string.h"
11 /* TODO: We should provide some generic mechanism for options caching. */
13 /* Fix namespace clash on Cygwin. */
14 #define option option_elinks
17 enum option_flags {
18 /* bitmask */
19 /* The option is hidden - it serves for internal purposes, never is
20 * read, never is written, never is displayed, never is crawled through
21 * etc. */
22 OPT_HIDDEN = 1,
23 /* For OPT_TREE, automatically create missing hiearchy piece just under
24 * this category when adding an option. The 'template' for the added
25 * hiearchy piece (category) is stored as "_template_" category. */
26 OPT_AUTOCREATE = 2,
27 /* This is used just for marking various options for some very dark,
28 * nasty and dirty purposes. This watermarking should be kept inside
29 * some very closed and clearly bounded piece of ELinks module, not
30 * spreaded along whole ELinks code, and you should clear it everytime
31 * when sneaking outside of the module (except some trivial common
32 * utility functions). Basically, you don't want to use this flag
33 * normally ;). It doesn't affect how the option is handled by common
34 * option handling functions in any way. */
35 OPT_WATERMARK = 4,
36 /* This is used to mark options modified after the last save. That's
37 * being useful if you want to save only the options whose value
38 * changed. */
39 OPT_TOUCHED = 8,
40 /* If set on the tree argument to add_opt (not necessarily the direct
41 * parent) or on the option itself, it will create the listbox (options
42 * manager) item for the option. */
43 OPT_LISTBOX = 16,
44 /* This is used to mark that the option _and_ the option name is
45 * allocated and should be freed when the option is released. */
46 OPT_ALLOC = 32,
47 /* For OPT_TREE, automatically sort the content of the tree
48 * alphabetically (but all subtrees in front of ordinary options) when
49 * adding new options. Note that this applies only to the one level
50 * below - it will not apply to the sub-trees in this tree. Also, this
51 * can be quite expensive for busy-adding big trees, so think twice
52 * before doing it - in fact, it is supposed to be used only where you
53 * add stuff from more modules, not all at once; typically the
54 * config_options root tree. Especially NOT RECOMMENDED to be used on
55 * the template trees. */
56 OPT_SORT = 64,
57 /* This is used to mark option as deleted */
58 OPT_DELETED = 128,
59 /* Specifies that values of boolean aliases should be inverted. */
60 OPT_ALIAS_NEGATE = 256
63 enum option_type {
64 OPT_BOOL = 0,
65 OPT_INT,
66 OPT_LONG,
67 OPT_STRING,
69 OPT_CODEPAGE,
70 OPT_LANGUAGE,
71 OPT_COLOR,
73 OPT_COMMAND,
75 OPT_ALIAS,
77 OPT_TREE,
80 struct listbox_item; /* bfu/listbox.h */
81 struct option; /* defined later in this file */
82 struct session; /* session/session.h */
84 union option_value {
85 /* XXX: Keep first to make @options_root initialization possible. */
86 /* The OPT_TREE list_head is allocated. */
87 struct list_head *tree;
89 /* Used by OPT_BOOL, OPT_INT, OPT_CODEPAGE and OPT_LANGUAGE */
90 int number;
92 /* Used by OPT_LONG */
93 long big_number;
95 /* The OPT_COLOR value */
96 color_T color;
98 /* The OPT_COMMAND value */
99 unsigned char *(*command)(struct option *, unsigned char ***, int *);
101 /* The OPT_STRING string is allocated and has length MAX_STR_LEN.
102 * The OPT_ALIAS string is NOT allocated, has variable length
103 * (opt->max) and should remain untouched! It contains the full path to
104 * the "real" / aliased option. */
105 unsigned char *string;
109 /* @session is the session via which the user changed the options,
110 * or NULL if not known. Because the options are currently not
111 * session-specific, it is best to ignore this parameter. In a future
112 * version of ELinks, this parameter might mean the session to which
113 * the changed options apply.
115 * @current is the option whose change hook is being called. It is
116 * never NULL.
118 * @changed is the option that was changed, or NULL if multiple
119 * descendants of @current may have been changed. */
120 typedef int (*change_hook_T)(struct session *session, struct option *current,
121 struct option *changed);
123 struct option {
124 OBJECT_HEAD(struct option);
126 unsigned char *name;
127 enum option_flags flags;
128 enum option_type type;
129 long min, max;
130 union option_value value;
131 unsigned char *desc;
132 unsigned char *capt;
134 struct option *root;
136 /* To be called when the option (or sub-option if it's a tree) is
137 * changed. If it returns zero, we will continue descending the options
138 * tree checking for change handlers. */
139 change_hook_T change_hook;
141 struct listbox_item *box_item;
144 #define INIT_OPTION(name, flags, type, min, max, value, desc, capt) \
145 { NULL_LIST_HEAD, INIT_OBJECT("option"), name, flags, type, min, max, { (struct list_head *) (value) }, desc, capt }
147 extern struct option *config_options;
148 extern struct option *cmdline_options;
151 extern void init_options(void);
152 extern void done_options(void);
155 struct change_hook_info {
156 unsigned char *name;
157 change_hook_T change_hook;
160 extern void register_change_hooks(const struct change_hook_info *change_hooks);
163 extern struct list_head *init_options_tree(void);
164 extern void unmark_options_tree(struct list_head *);
165 void watermark_deleted_options(struct list_head *);
167 extern void smart_config_string(struct string *, int, int, struct list_head *, unsigned char *, int,
168 void (*)(struct string *, struct option *, unsigned char *, int, int, int, int));
170 extern struct option *copy_option(struct option *);
171 extern void delete_option(struct option *);
172 void mark_option_as_deleted(struct option *);
174 /* Some minimal option cache */
176 struct option_resolver {
177 int id;
178 unsigned char *name;
181 /* Update the visibility of the box item of each option
182 * in config_options to honour the value of config.show_template. */
183 void update_options_visibility(void);
185 /* Toggle the value of the given option numeric, respecting option->min
186 * and option->max. */
187 void toggle_option(struct session *ses, struct option *option);
189 /* Call the change-hooks for the given option and recur on its parent. */
190 void call_change_hooks(struct session *ses, struct option *current,
191 struct option *option);
193 /* Do proper bookkeeping after an option has changed - call this every time
194 * you change an option value. */
195 void option_changed(struct session *ses, struct option *option);
197 extern int commit_option_values(struct option_resolver *resolvers,
198 struct option *root,
199 union option_value *values, int size);
200 extern void checkout_option_values(struct option_resolver *resolvers,
201 struct option *root,
202 union option_value *values, int size);
204 /* Shitload of various incredible macro combinations and other unusable garbage
205 * follows. Have fun. */
207 /* Basically, for main hiearchy addressed from root (almost always) you want to
208 * use get_opt_type() and add_opt_type(). For command line options, you want to
209 * use get_opt_type_tree(cmdline_options, "option"). */
211 extern struct option *get_opt_rec(struct option *, const unsigned char *);
212 extern struct option *get_opt_rec_real(struct option *, const unsigned char *);
213 #ifdef CONFIG_DEBUG
214 extern union option_value *get_opt_(unsigned char *, int, enum option_type, struct option *, unsigned char *);
215 #define get_opt(tree, name, type) get_opt_(__FILE__, __LINE__, type, tree, name)
216 #else
217 extern union option_value *get_opt_(struct option *, unsigned char *);
218 #define get_opt(tree, name, type) get_opt_(tree, name)
219 #endif
221 #define get_opt_bool_tree(tree, name) get_opt(tree, name, OPT_BOOL)->number
222 #define get_opt_int_tree(tree, name) get_opt(tree, name, OPT_INT)->number
223 #define get_opt_long_tree(tree, name) get_opt(tree, name, OPT_LONG)->big_number
224 #define get_opt_str_tree(tree, name) get_opt(tree, name, OPT_STRING)->string
225 #define get_opt_codepage_tree(tree, name) get_opt(tree, name, OPT_CODEPAGE)->number
226 #define get_opt_color_tree(tree, name) get_opt(tree, name, OPT_COLOR)->color
227 #define get_opt_tree_tree(tree_, name) get_opt(tree_, name, OPT_TREE)->tree
229 #define get_opt_bool(name) get_opt_bool_tree(config_options, name)
230 #define get_opt_int(name) get_opt_int_tree(config_options, name)
231 #define get_opt_long(name) get_opt_long_tree(config_options, name)
232 #define get_opt_str(name) get_opt_str_tree(config_options, name)
233 #define get_opt_codepage(name) get_opt_codepage_tree(config_options, name)
234 #define get_opt_color(name) get_opt_color_tree(config_options, name)
235 #define get_opt_tree(name) get_opt_tree_tree(config_options, name)
237 #define get_cmd_opt_bool(name) get_opt_bool_tree(cmdline_options, name)
238 #define get_cmd_opt_int(name) get_opt_int_tree(cmdline_options, name)
239 #define get_cmd_opt_long(name) get_opt_long_tree(cmdline_options, name)
240 #define get_cmd_opt_str(name) get_opt_str_tree(cmdline_options, name)
241 #define get_cmd_opt_codepage(name) get_opt_codepage_tree(cmdline_options, name)
242 #define get_cmd_opt_color(name) get_opt_color_tree(cmdline_options, name)
243 #define get_cmd_opt_tree(name) get_opt_tree_tree(cmdline_options, name)
245 extern struct option *add_opt(struct option *, unsigned char *, unsigned char *,
246 unsigned char *, enum option_flags, enum option_type,
247 long, long, longptr_T, unsigned char *);
249 /* Hack which permit to disable option descriptions, to reduce elinks binary size.
250 * It may of some use for people wanting a very small static non-i18n elinks binary,
251 * at time of writing gain is over 25Kbytes. --Zas */
252 #ifndef CONFIG_SMALL
253 #define DESC(x) (x)
254 #else
255 #define DESC(x) ((unsigned char *) "")
256 #endif
259 #define add_opt_bool_tree(tree, path, capt, name, flags, def, desc) \
260 add_opt(tree, path, capt, name, flags, OPT_BOOL, 0, 1, (longptr_T) def, DESC(desc))
262 #define add_opt_int_tree(tree, path, capt, name, flags, min, max, def, desc) \
263 add_opt(tree, path, capt, name, flags, OPT_INT, min, max, (longptr_T) def, DESC(desc))
265 #define add_opt_long_tree(tree, path, capt, name, flags, min, max, def, desc) \
266 add_opt(tree, path, capt, name, flags, OPT_LONG, min, max, (longptr_T) def, DESC(desc))
268 #define add_opt_str_tree(tree, path, capt, name, flags, def, desc) \
269 do { \
270 unsigned char *ptr = mem_alloc(MAX_STR_LEN); \
271 safe_strncpy(ptr, def, MAX_STR_LEN); \
272 add_opt(tree, path, capt, name, flags, OPT_STRING, 0, MAX_STR_LEN, (longptr_T) ptr, DESC(desc)); \
273 } while (0)
275 #define add_opt_codepage_tree(tree, path, capt, name, flags, def, desc) \
276 add_opt(tree, path, capt, name, flags, OPT_CODEPAGE, 0, 0, (longptr_T) get_cp_index(def), DESC(desc))
278 #define add_opt_lang_tree(tree, path, capt, name, flags, desc) \
279 add_opt(tree, path, capt, name, flags, OPT_LANGUAGE, 0, 0, (longptr_T) 0, DESC(desc))
281 #define add_opt_color_tree(tree, path, capt, name, flags, def, desc) \
282 add_opt(tree, path, capt, name, flags, OPT_COLOR, 0, 0, (longptr_T) def, DESC(desc))
284 #define add_opt_command_tree(tree, path, capt, name, flags, cmd, desc) \
285 add_opt(tree, path, capt, name, flags, OPT_COMMAND, 0, 0, (longptr_T) cmd, DESC(desc));
287 #define add_opt_alias_tree(tree, path, capt, name, flags, def, desc) \
288 add_opt(tree, path, capt, name, flags, OPT_ALIAS, 0, strlen(def), (longptr_T) def, DESC(desc))
290 #define add_opt_tree_tree(tree, path, capt, name, flags, desc) \
291 add_opt(tree, path, capt, name, flags, OPT_TREE, 0, 0, (longptr_T) init_options_tree(), DESC(desc));
294 /* Builtin options */
296 struct option_info {
297 struct option option;
298 unsigned char *path;
301 extern void register_options(struct option_info info[], struct option *tree);
302 extern void unregister_options(struct option_info info[], struct option *tree);
304 #define NULL_OPTION_INFO \
305 { INIT_OPTION(NULL, 0, 0, 0, 0, NULL, NULL, NULL), NULL }
307 #define INIT_OPT_BOOL(path, capt, name, flags, def, desc) \
308 { INIT_OPTION(name, flags, OPT_BOOL, 0, 1, def, DESC(desc), capt), path }
310 #define INIT_OPT_INT(path, capt, name, flags, min, max, def, desc) \
311 { INIT_OPTION(name, flags, OPT_INT, min, max, def, DESC(desc), capt), path }
313 #define INIT_OPT_LONG(path, capt, name, flags, min, max, def, desc) \
314 { INIT_OPTION(name, flags, OPT_LONG, min, max, def, DESC(desc), capt), path }
316 #define INIT_OPT_STRING(path, capt, name, flags, def, desc) \
317 { INIT_OPTION(name, flags, OPT_STRING, 0, MAX_STR_LEN, def, DESC(desc), capt), path }
319 #define INIT_OPT_CODEPAGE(path, capt, name, flags, def, desc) \
320 { INIT_OPTION(name, flags, OPT_CODEPAGE, 0, 0, def, DESC(desc), capt), path }
322 #define INIT_OPT_COLOR(path, capt, name, flags, def, desc) \
323 { INIT_OPTION(name, flags, OPT_COLOR, 0, 0, def, DESC(desc), capt), path }
325 #define INIT_OPT_LANGUAGE(path, capt, name, flags, desc) \
326 { INIT_OPTION(name, flags, OPT_LANGUAGE, 0, 0, 0, DESC(desc), capt), path }
328 #define INIT_OPT_COMMAND(path, capt, name, flags, cmd, desc) \
329 { INIT_OPTION(name, flags, OPT_COMMAND, 0, 0, cmd, DESC(desc), capt), path }
331 #define INIT_OPT_CMDALIAS(path, capt, name, flags, def, desc) \
332 { INIT_OPTION(name, flags, OPT_ALIAS, 0, sizeof(def) - 1, def, DESC(desc), capt), path }
334 #define INIT_OPT_ALIAS(path, name, flags, def) \
335 { INIT_OPTION(name, flags, OPT_ALIAS, 0, sizeof(def) - 1, def, NULL, NULL), path }
337 #define INIT_OPT_TREE(path, capt, name, flags, desc) \
338 { INIT_OPTION(name, flags, OPT_TREE, 0, 0, NULL, DESC(desc), capt), path }
341 /* TODO: We need to do *something* with this ;). */
343 enum referer {
344 REFERER_NONE,
345 REFERER_SAME_URL,
346 REFERER_FAKE,
347 REFERER_TRUE,
350 enum verbose_level {
351 VERBOSE_QUIET,
352 VERBOSE_WARNINGS,
353 VERBOSE_ALL,
355 VERBOSE_LEVELS,
358 #endif