1 /*
2  * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
3  *
4  * This file is part of NetSurf, http://www.netsurf-browser.org/
5  *
6  * NetSurf is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * NetSurf is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /**
20  * \file
21  * Option reading and saving interface.
22  *
23  * Global options are defined in desktop/options.h
24  * Distinct target options are defined in ${TARGET}/options.h
25  *
26  * The implementation API is slightly compromised because it still has
27  * "global" tables for both the default and current option tables.
28  *
29  * The initialisation and read/write interfaces take pointers to an
30  * option table which would let us to make the option structure
31  * opaque.
32  *
33  * All the actual acessors assume direct access to a global option
34  * table (nsoptions). To avoid this the acessors would have to take a
35  * pointer to the active options table and be implemented as functions
36  * within nsoptions.c
37  *
38  * Indirect access would have an impact on performance of NetSurf as
39  * the expected option lookup cost is currently that of a simple
40  * dereference (which this current implementation keeps).
41  */
42 
43 #ifndef _NETSURF_UTILS_NSOPTION_H_
44 #define _NETSURF_UTILS_NSOPTION_H_
45 
46 #include <stdio.h>
47 #include <stdint.h>
48 #include <stdbool.h>
49 
50 #include "utils/errors.h"
51 
52 /* allow targets to include any necessary headers of their own */
53 #define NSOPTION_BOOL(NAME, DEFAULT)
54 #define NSOPTION_STRING(NAME, DEFAULT)
55 #define NSOPTION_INTEGER(NAME, DEFAULT)
56 #define NSOPTION_UINT(NAME, DEFAULT)
57 #define NSOPTION_COLOUR(NAME, DEFAULT)
58 
59 #include "desktop/options.h"
60 #if defined(riscos)
61 #include "riscos/options.h"
62 #elif defined(nsgtk)
63 #include "gtk/options.h"
64 #elif defined(nsbeos)
65 #include "beos/options.h"
66 #elif defined(nsamiga)
67 #include "amiga/options.h"
68 #elif defined(nsframebuffer)
69 #include "framebuffer/options.h"
70 #elif defined(nsatari)
71 #include "atari/options.h"
72 #elif defined(nsmonkey)
73 #include "monkey/options.h"
74 #elif defined(nswin32)
75 #include "windows/options.h"
76 #endif
77 
78 #undef NSOPTION_BOOL
79 #undef NSOPTION_STRING
80 #undef NSOPTION_INTEGER
81 #undef NSOPTION_UINT
82 #undef NSOPTION_COLOUR
83 
84 
85 
86 enum { OPTION_HTTP_PROXY_AUTH_NONE = 0,
87        OPTION_HTTP_PROXY_AUTH_BASIC = 1,
88        OPTION_HTTP_PROXY_AUTH_NTLM = 2 };
89 
90 #define DEFAULT_MARGIN_TOP_MM 10
91 #define DEFAULT_MARGIN_BOTTOM_MM 10
92 #define DEFAULT_MARGIN_LEFT_MM 10
93 #define DEFAULT_MARGIN_RIGHT_MM 10
94 #define DEFAULT_EXPORT_SCALE 0.7
95 
96 #ifndef DEFAULT_REFLOW_PERIOD
97 /** Default reflow time in cs */
98 #define DEFAULT_REFLOW_PERIOD 25
99 #endif
100 
101 /** The options type. */
102 enum nsoption_type_e {
103 	OPTION_BOOL, /**< Option is a boolean. */
104 	OPTION_INTEGER, /**< Option is an integer. */
105 	OPTION_UINT, /**< Option is an unsigned integer */
106 	OPTION_STRING, /**< option is a heap allocated string. */
107 	OPTION_COLOUR /**< Option  is a netsurf colour. */
108 };
109 
110 struct nsoption_s {
111 	const char *key;
112 	int key_len;
113 	enum nsoption_type_e type;
114 	union {
115 		bool b;
116 		int i;
117 		unsigned int u;
118 		char *s;
119 		const char *cs;
120 		colour c;
121 	} value;
122 };
123 
124 /* construct the option enumeration */
125 #define NSOPTION_BOOL(NAME, DEFAULT) NSOPTION_##NAME,
126 #define NSOPTION_STRING(NAME, DEFAULT) NSOPTION_##NAME,
127 #define NSOPTION_INTEGER(NAME, DEFAULT) NSOPTION_##NAME,
128 #define NSOPTION_UINT(NAME, DEFAULT) NSOPTION_##NAME,
129 #define NSOPTION_COLOUR(NAME, DEFAULT) NSOPTION_##NAME,
130 
131 enum nsoption_e {
132 #include "desktop/options.h"
133 #if defined(riscos)
134 #include "riscos/options.h"
135 #elif defined(nsgtk)
136 #include "gtk/options.h"
137 #elif defined(nsbeos)
138 #include "beos/options.h"
139 #elif defined(nsamiga)
140 #include "amiga/options.h"
141 #elif defined(nsframebuffer)
142 #include "framebuffer/options.h"
143 #elif defined(nsatari)
144 #include "atari/options.h"
145 #elif defined(nsmonkey)
146 #include "monkey/options.h"
147 #elif defined(nswin32)
148 #include "windows/options.h"
149 #endif
150 	NSOPTION_LISTEND /* end of list */
151 };
152 
153 #undef NSOPTION_BOOL
154 #undef NSOPTION_STRING
155 #undef NSOPTION_INTEGER
156 #undef NSOPTION_UINT
157 #undef NSOPTION_COLOUR
158 
159 /**
160  * global active option table.
161  */
162 extern struct nsoption_s *nsoptions;
163 
164 /**
165  * global default option table.
166  */
167 extern struct nsoption_s *nsoptions_default;
168 
169 /**
170  * default setting callback.
171  */
172 typedef nserror(nsoption_set_default_t)(struct nsoption_s *defaults);
173 
174 
175 /**
176  * Initialise option system.
177  *
178  * @param set_default callback to allow the customisation of the default
179  *                    options.
180  * @param popts pointer to update to get options table or NULL.
181  * @param pdefs pointer to update to get default options table or NULL.
182  * @return The error status
183  */
184 nserror nsoption_init(nsoption_set_default_t *set_default, struct nsoption_s **popts, struct nsoption_s **pdefs);
185 
186 
187 /**
188  * Finalise option system
189  *
190  * Releases all resources allocated in the initialisation.
191  *
192  * @param opts the options table or NULL to use global table.
193  * @param defs the default options table to use or NULL to use global table
194  * return The error status
195  */
196 nserror nsoption_finalise(struct nsoption_s *opts, struct nsoption_s *defs);
197 
198 
199 /**
200  * Read choices file and set them in the passed table
201  *
202  * @param path The path to read the file from
203  * @param opts The options table to enerate values from or NULL to use global
204  * @return The error status
205  */
206 nserror nsoption_read(const char *path, struct nsoption_s *opts);
207 
208 
209 /**
210  * Write options that have changed from the defaults to a file.
211  *
212  * The \a nsoption_dump can be used to output all entries not just
213  * changed ones.
214  *
215  * @param path The path to read the file from
216  * @param opts The options table to enerate values from or NULL to use global
217  * @param defs The default table to use or NULL to use global
218  * @return The error status
219  */
220 nserror nsoption_write(const char *path, struct nsoption_s *opts, struct nsoption_s *defs);
221 
222 
223 /**
224  * Write all options to a stream.
225  *
226  * @param outf The stream to write to
227  * @param opts The options table to enerate values from or NULL to use global
228  * @return The error status
229  */
230 nserror nsoption_dump(FILE *outf, struct nsoption_s *opts);
231 
232 
233 /**
234  * Process commandline and set options approriately.
235  *
236  * @param pargc Pointer to the size of the argument vector.
237  * @param argv The argument vector.
238  * @param opts The options table to enerate values from or NULL to use global
239  * @return The error status
240  */
241 nserror nsoption_commandline(int *pargc, char **argv, struct nsoption_s *opts);
242 
243 
244 /**
245  * Fill a buffer with an option using a format.
246  *
247  * The format string is copied into the output buffer with the
248  * following replaced:
249  * %k - The options key
250  * %t - The options type
251  * %V - value (HTML formatting)
252  * %v - value (plain formatting)
253  * %p - provenance either "user" or "default"
254  *
255  * @param string The buffer in which to place the results.
256  * @param size The size of the string buffer.
257  * @param option The option .
258  * @param fmt The format string.
259  * @return The number of bytes written to \a string or -1 on error
260  */
261 int nsoption_snoptionf(char *string, size_t size, enum nsoption_e option, const char *fmt);
262 
263 
264 /**
265  * Get the value of a boolean option.
266  *
267  * Gets the value of an option assuming it is a boolean type.
268  * @note option type is unchecked so care must be taken in caller.
269  */
270 #define nsoption_bool(OPTION) (nsoptions[NSOPTION_##OPTION].value.b)
271 
272 
273 /**
274  * Get the value of an integer option.
275  *
276  * Gets the value of an option assuming it is a integer type.
277  * @note option type is unchecked so care must be taken in caller.
278  */
279 #define nsoption_int(OPTION) (nsoptions[NSOPTION_##OPTION].value.i)
280 
281 
282 /**
283  * Get the value of an unsigned integer option.
284  *
285  * Gets the value of an option assuming it is a integer type.
286  * @note option type is unchecked so care must be taken in caller.
287  */
288 #define nsoption_uint(OPTION) (nsoptions[NSOPTION_##OPTION].value.u)
289 
290 
291 /**
292  * Get the value of a string option.
293  *
294  * Gets the value of an option assuming it is a string type.
295  * @note option type is unchecked so care must be taken in caller.
296  */
297 #define nsoption_charp(OPTION) (nsoptions[NSOPTION_##OPTION].value.s)
298 
299 
300 /**
301  * Get the value of a netsurf colour option.
302  *
303  * Gets the value of an option assuming it is a colour type.
304  * @note option type is unchecked so care must be taken in caller.
305  */
306 #define nsoption_colour(OPTION) (nsoptions[NSOPTION_##OPTION].value.c)
307 
308 
309 /** set a boolean option in the default table */
310 #define nsoption_set_bool(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.b = VALUE
311 
312 
313 /** set an integer option in the default table */
314 #define nsoption_set_int(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.i = VALUE
315 
316 /** set an unsigned integer option in the default table */
317 #define nsoption_set_uint(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.u = VALUE
318 
319 
320 /** set a colour option in the default table */
321 #define nsoption_set_colour(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.c = VALUE
322 
323 
324 /**
325  * Set string option in specified table.
326  *
327  * Sets the string option to the value given freeing any resources
328  * currently allocated to the option. If the passed string is empty it
329  * is converted to the NULL value.
330  *
331  * @param opts The table to set option in
332  * @param option_idx The option
333  * @param s The string to set. This is used directly and not copied.
334  */
335 nserror nsoption_set_tbl_charp(struct nsoption_s *opts, enum nsoption_e option_idx, char *s);
336 
337 /** set string option in default table */
338 #define nsoption_set_charp(OPTION, VALUE) \
339 	nsoption_set_tbl_charp(nsoptions, NSOPTION_##OPTION, VALUE)
340 
341 /** set string option in default table if currently unset */
342 #define nsoption_setnull_charp(OPTION, VALUE)				\
343 	do {								\
344 		if (nsoptions[NSOPTION_##OPTION].value.s == NULL) {	\
345 			nsoption_set_tbl_charp(nsoptions, NSOPTION_##OPTION, VALUE); \
346 		} else {						\
347 			free(VALUE);					\
348 		}							\
349 	} while (0)
350 
351 #endif
352