summaryrefslogtreecommitdiff
path: root/utils/nsoption.h
blob: 868e077bd908a2f38389461079dcac81f04f87f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/*
 * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
 *
 * This file is part of NetSurf, http://www.netsurf-browser.org/
 *
 * NetSurf is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * NetSurf is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/** \file
 * Option reading and saving (interface).
 *
 * Global options are defined in desktop/options.h
 * Distinct target options are defined in <TARGET>/options.h
 *
 * The implementation API is slightly compromised because it still has
 * "global" tables for both the default and current option tables.
 *
 * The initialisation and read/write interfaces take pointers to an
 * option table which would let us to make the option structure
 * opaque.
 *
 * All the actual acessors assume direct access to a global option
 * table (nsoptions). To avoid this the acessors would have to take a
 * pointer to the active options table and be implemented as functions
 * within nsoptions.c
 *
 * Indirect acees would have an impact on performance of NetSurf as
 * the expected option lookup cost is currently that of a simple
 * dereference (which this current implementation keeps).
 */

#ifndef _NETSURF_UTILS_NSOPTION_H_
#define _NETSURF_UTILS_NSOPTION_H_

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

#include "utils/errors.h"

/* allow targets to include any necessary headers of their own */
#define NSOPTION_BOOL(NAME, DEFAULT)
#define NSOPTION_STRING(NAME, DEFAULT)
#define NSOPTION_INTEGER(NAME, DEFAULT)
#define NSOPTION_UINT(NAME, DEFAULT)
#define NSOPTION_COLOUR(NAME, DEFAULT)

#include "desktop/options.h"
#if defined(riscos)
#include "riscos/options.h"
#elif defined(nsgtk)
#include "gtk/options.h"
#elif defined(nsbeos)
#include "beos/options.h"
#elif defined(nsamiga)
#include "amiga/options.h"
#elif defined(nsframebuffer)
#include "framebuffer/options.h"
#elif defined(nsatari)
#include "atari/options.h"
#elif defined(nsmonkey)
#include "monkey/options.h"
#endif

#undef NSOPTION_BOOL
#undef NSOPTION_STRING
#undef NSOPTION_INTEGER
#undef NSOPTION_UINT
#undef NSOPTION_COLOUR



enum { OPTION_HTTP_PROXY_AUTH_NONE = 0,
       OPTION_HTTP_PROXY_AUTH_BASIC = 1,
       OPTION_HTTP_PROXY_AUTH_NTLM = 2 };

#define DEFAULT_MARGIN_TOP_MM 10
#define DEFAULT_MARGIN_BOTTOM_MM 10
#define DEFAULT_MARGIN_LEFT_MM 10
#define DEFAULT_MARGIN_RIGHT_MM 10
#define DEFAULT_EXPORT_SCALE 0.7

#ifndef DEFAULT_REFLOW_PERIOD
#define DEFAULT_REFLOW_PERIOD 25 /* time in cs */
#endif

enum nsoption_type_e {
	OPTION_BOOL,
	OPTION_INTEGER,
	OPTION_UINT,
	OPTION_STRING,
	OPTION_COLOUR
};

struct nsoption_s {
	const char *key;
	int key_len;
	enum nsoption_type_e type;
	union {
		bool b;
		int i;
		unsigned int u;
		char *s;
		const char *cs;
		colour c;
	} value;
};

/* construct the option enumeration */
#define NSOPTION_BOOL(NAME, DEFAULT) NSOPTION_##NAME,
#define NSOPTION_STRING(NAME, DEFAULT) NSOPTION_##NAME,
#define NSOPTION_INTEGER(NAME, DEFAULT) NSOPTION_##NAME,
#define NSOPTION_UINT(NAME, DEFAULT) NSOPTION_##NAME,
#define NSOPTION_COLOUR(NAME, DEFAULT) NSOPTION_##NAME,

enum nsoption_e {
#include "desktop/options.h"
#if defined(riscos)
#include "riscos/options.h"
#elif defined(nsgtk)
#include "gtk/options.h"
#elif defined(nsbeos)
#include "beos/options.h"
#elif defined(nsamiga)
#include "amiga/options.h"
#elif defined(nsframebuffer)
#include "framebuffer/options.h"
#elif defined(nsatari)
#include "atari/options.h"
#elif defined(nsmonkey)
#include "monkey/options.h"
#endif
	NSOPTION_LISTEND /* end of list */
};

#undef NSOPTION_BOOL
#undef NSOPTION_STRING
#undef NSOPTION_INTEGER
#undef NSOPTION_UINT
#undef NSOPTION_COLOUR

/* global option table */
extern struct nsoption_s *nsoptions;

/* global default option table */
extern struct nsoption_s *nsoptions_default;

/* default setting callback */
typedef nserror(nsoption_set_default_t)(struct nsoption_s *defaults);


/** Initialise option system.
 *
 * @param set_default callback to allow the customisation of the default
 *                    options.
 * @param ppots pointer to update to get options table or NULL.
 * @param pdefs pointer to update to get default options table or NULL.
 * @return The error status
 */
nserror nsoption_init(nsoption_set_default_t *set_default, struct nsoption_s **popts, struct nsoption_s **pdefs);


/** Read choices file and set them in the passed table
 *
 * @param path The path to read the file from
 * @param opts The options table to enerate values from or NULL to use global
 * @return The error status
 */
nserror nsoption_read(const char *path, struct nsoption_s *opts);


/** Write options that have changed from the defaults to a file.
 *
 * The \a nsoption_dump can be used to output all entries not just
 * changed ones.
 *
 * @param path The path to read the file from
 * @param opts The options table to enerate values from or NULL to use global
 * @param defs The default table to use or NULL to use global
 * @return The error status
 */
nserror nsoption_write(const char *path, struct nsoption_s *opts, struct nsoption_s *defs);


/**
 * Write all options to a stream.
 *
 * @param outf The stream to write to
 * @param opts The options table to enerate values from or NULL to use global
 * @return The error status
 */
nserror nsoption_dump(FILE *outf, struct nsoption_s *opts);

/**
 * Process commandline and set options approriately.
 *
 * @param pargc Pointer to the size of the argument vector.
 * @param argv The argument vector.
 * @param opts The options table to enerate values from or NULL to use global
 * @return The error status
 */
nserror nsoption_commandline(int *pargc, char **argv, struct nsoption_s *opts);

/**
 * Fill a buffer with an option using a format.
 *
 * The format string is copied into the output buffer with the
 * following replaced:
 * %k - The options key
 * %t - The options type
 * %V - value (HTML formatting)
 * %v - value (plain formatting)
 * %p - provenance either "user" or "default"
 *
 * @param string The buffer in which to place the results.
 * @param size The size of the string buffer.
 * @param option The option .
 * @param fmt The format string.
 * @return The number of bytes written to \a string or -1 on error
 */
int nsoption_snoptionf(char *string, size_t size, enum nsoption_e option, const char *fmt);




/* value acessors - caution should be taken with type as this is not verified */
#define nsoption_bool(OPTION) (nsoptions[NSOPTION_##OPTION].value.b)
#define nsoption_int(OPTION) (nsoptions[NSOPTION_##OPTION].value.i)
#define nsoption_uint(OPTION) (nsoptions[NSOPTION_##OPTION].value.u)
#define nsoption_charp(OPTION) (nsoptions[NSOPTION_##OPTION].value.s)
#define nsoption_colour(OPTION) (nsoptions[NSOPTION_##OPTION].value.c)

#define nsoption_set_bool(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.b = VALUE
#define nsoption_set_int(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.i = VALUE
#define nsoption_set_colour(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.c = VALUE
#define nsoption_set_charp(OPTION, VALUE)				\
	do {								\
		if (nsoptions[NSOPTION_##OPTION].value.s != NULL) {	\
			free(nsoptions[NSOPTION_##OPTION].value.s);	\
		}							\
		nsoptions[NSOPTION_##OPTION].value.s = VALUE;		\
		if ((nsoptions[NSOPTION_##OPTION].value.s != NULL) &&	\
		    (*nsoptions[NSOPTION_##OPTION].value.s == 0)) {	\
			free(nsoptions[NSOPTION_##OPTION].value.s);	\
			nsoptions[NSOPTION_##OPTION].value.s = NULL;	\
		}							\
	} while (0)

/* if a string option is unset set it otherwise leave it set */
#define nsoption_setnull_charp(OPTION, VALUE)				\
	do {								\
		if (nsoptions[NSOPTION_##OPTION].value.s == NULL) {	\
			nsoptions[NSOPTION_##OPTION].value.s = VALUE;	\
			if (*nsoptions[NSOPTION_##OPTION].value.s == 0) { \
				free(nsoptions[NSOPTION_##OPTION].value.s); \
				nsoptions[NSOPTION_##OPTION].value.s = NULL; \
			}						\
		} else {						\
			free(VALUE);					\
		}							\
	} while (0)


#endif