[elinks-dev] [PATCH] Use union type for option values

Jonas Fonseca fonseca at diku.dk
Tue Oct 21 17:33:29 PDT 2003


Karsten Schölzel <kuser at gmx.de> wrote Tue, Oct 21, 2003:
> On Tue, Oct 21, 2003 at 11:01:01PM +0200, Jonas Fonseca wrote:
> > Karsten Schölzel <kuser at gmx.de> wrote Tue, Oct 21, 2003:
> > > On Tue, Oct 21, 2003 at 09:15:22PM +0200, Jonas Fonseca wrote:
> > > [...]
> > > > @@ -3021,20 +3052,19 @@
> > > >  
> > > >  
> > > >  	/* Some default pre-autocreated options. Doh. */
> > > > -
> > > > -	get_opt_int("terminal.linux.type") = 2;
> > > [...]
> > > 	set_opt_value("terminal.linux.type", number, 2);
> > 
> > 	get_opt_value("terminal.linux.type)->number = 2;
> > 
> > Almost the same :)
> > 
> If i read it right get_opt_int(name) is identically to
> get_opt_value(name)->number, so there is no need to change anything in
> this statements :)

Wow, how could I miss that? :/

This nicely reduces the patch. Plus I also trimmed the unnecessary candy
so a few clean-follow-ups will probably be needed. Most of the patch now
consists of trivial "ugly cast" -> union type dereference changes.

This patch has a few fixes from the previous among them a fix for
language string printing in print_full_help() (one of two type fixes so
the type safety has already has paid off) and a fix of a wrong union
type usage.

Both tree, alias and string option adding now allocates memory in the
add_opt_<type>() macro. Pasky requested it for trees and for consistency
the others do it as well. For strings memacpy(..., MAX_STR_LEN - 1), is
used and for aliases (since they _never_ change) we use stracpy() and
save a few bytes there as well.

 config/conf.c            |    4 -
 config/options.c         |  120 ++++++++++++++++++++++++++++-------------------
 config/options.h         |   82 +++++++++++---------------------
 config/opttypes.c        |  100 +++++++++++++--------------------------
 dialogs/mime.c           |    8 +--
 dialogs/options.c        |    8 +--
 globhist/dialogs.c       |    4 -
 mime/backend/default.c   |    8 +--
 mime/backend/mailcap.c   |    2
 mime/backend/mimetypes.c |    2
 protocol/user.c          |    2
 viewer/text/search.c     |    8 +--
 viewer/text/view.c       |    2
 13 files changed, 161 insertions(+), 189 deletions(-)

I hope we have a winnner! ;)

-- 
Jonas Fonseca
-------------- next part --------------
? 1063623931-17.10.2003-22:00-1.html
? TODO
? att.ht
? config-1
? config-2
? config-3
? contact.html
? elinks-optunion
? elinks.d
? elinks.dir
? first-step.patch
? first_step.patch
? next.patch
? option-value-union.patch
? renderer.c
? screen.c
? screen.c.next
? document/html/renderer.c-1.59
? viewer/viewer.c
? viewer/viewer.h
Index: config/conf.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/config/conf.c,v
retrieving revision 1.94
diff -u -d -r1.94 conf.c
--- config/conf.c	20 Oct 2003 15:42:17 -0000	1.94
+++ config/conf.c	22 Oct 2003 00:20:25 -0000
@@ -636,7 +636,7 @@
 	add_to_string(&tmpstring, "#\n\n");
 
 	origlen = tmpstring.length;
-	smart_config_string(&tmpstring, 2, i18n, options->ptr, NULL, 0, smart_config_output_fn);
+	smart_config_string(&tmpstring, 2, i18n, options->value.tree, NULL, 0, smart_config_output_fn);
 	if (tmpstring.length > origlen)
 		add_bytes_to_string(&config, tmpstring.source, tmpstring.length);
 	done_string(&tmpstring);
@@ -656,7 +656,7 @@
 	done_string(&tmpstring);
 
 get_me_out:
-	unmark_options_tree(options->ptr);
+	unmark_options_tree(options->value.tree);
 
 	return config.source;
 }
Index: config/options.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/config/options.c,v
retrieving revision 1.322
diff -u -d -r1.322 options.c
--- config/options.c	21 Oct 2003 15:36:25 -0000	1.322
+++ config/options.c	22 Oct 2003 00:20:27 -0000
@@ -56,6 +56,8 @@
  * (struct option *) instead. This applies to bookmarks, global history and
  * listbox items as well, though. --pasky */
 
+static INIT_LIST_HEAD(options_root_tree);
+
 static struct option options_root = {
 	NULL_LIST_HEAD,
 
@@ -63,7 +65,7 @@
 	/* flags: */	0,
 	/* type: */	OPT_TREE,
 	/* min, max: */	0, 0,
-	/* ptr: */	NULL,
+	/* value: */	{ &options_root_tree },
 	/* desc: */	"",
 	/* capt: */	NULL,
 };
@@ -118,7 +120,7 @@
 		name = sep + 1;
 	}
 
-	foreach (option, *((struct list_head *) tree->ptr)) {
+	foreach (option, *tree->value.tree) {
 		if (option->name && !strcmp(option->name, name)) {
 			mem_free(aname);
 			return option;
@@ -176,7 +178,7 @@
 
 /* Fetch pointer to value of certain option. It is guaranteed to never return
  * NULL. Note that you are supposed to use wrapper get_opt(). */
-void *
+union option_value *
 get_opt_(
 #ifdef DEBUG
 	 unsigned char *file, int line,
@@ -189,21 +191,22 @@
 	errfile = file;
 	errline = line;
 	if (!opt) elinks_internal("Attempted to fetch nonexisting option %s!", name);
-	if (!opt->ptr) elinks_internal("Option %s has no value!", name);
+	if ((opt->type == OPT_STRING || opt->type == OPT_ALIAS)
+	    && !opt->value.string) elinks_internal("Option %s has no value!", name);
 #endif
 
-	return opt->ptr;
+	return &opt->value;
 }
 
 /* Add option to tree. */
 static void
 add_opt_rec(struct option *tree, unsigned char *path, struct option *option)
 {
-	struct list_head *cat = tree->ptr;
+	struct list_head *cat = tree->value.tree;
 
 	if (*path) {
 		tree = get_opt_rec(tree, path);
-		cat = tree->ptr;
+		cat = tree->value.tree;
 	}
 	if (!cat) return;
 
@@ -225,7 +228,7 @@
 struct option *
 add_opt(struct option *tree, unsigned char *path, unsigned char *capt,
 	unsigned char *name, enum option_flags flags, enum option_type type,
-	int min, int max, void *ptr, unsigned char *desc)
+	int min, int max, void *value, unsigned char *desc)
 {
 	struct option *option = mem_calloc(1, sizeof(struct option));
 
@@ -240,7 +243,6 @@
 	option->type = type;
 	option->min = min;
 	option->max = max;
-	option->ptr = ptr;
 	option->capt = capt;
 	option->desc = desc;
 
@@ -261,6 +263,37 @@
 		}
 	}
 
+	/* XXX: For allocated values we allocate in the add_opt_<type>() macro.
+	 * This involves OPT_TREE, OPT_STRING and OPT_ALIAS. */
+	/* TODO: Check for allocation failure */
+	switch (type) {
+		case OPT_TREE:
+			option->value.tree = value;
+			break;
+		case OPT_STRING:
+		case OPT_ALIAS:
+			option->value.string = value;
+			break;
+		case OPT_BOOL:
+		case OPT_INT:
+		case OPT_LONG:
+		case OPT_CODEPAGE:
+			option->value.number = (long) value;
+			break;
+		case OPT_COLOR:
+			decode_color(value, &option->value.color);
+			break;
+		case OPT_COMMAND:
+			option->value.command = value;
+			break;
+		case OPT_LANGUAGE:
+			break;
+		default:
+			/* XXX: Make sure all option types are handled here. */
+			internal("Invalid option type %d", type);
+			break;
+	}
+
 	add_opt_rec(tree, path, option);
 	return option;
 }
@@ -275,21 +308,14 @@
 void
 free_option_value(struct option *option)
 {
-	if (option->type == OPT_TREE) {
-		free_options_tree((struct list_head *) option->ptr);
-	}
-
 	switch (option->type) {
-		case OPT_BOOL:
-		case OPT_INT:
-		case OPT_LONG:
 		case OPT_STRING:
-		case OPT_LANGUAGE:
-		case OPT_CODEPAGE:
-		case OPT_COLOR:
 		case OPT_ALIAS:
+			mem_free(option->value.string);
+			break;
 		case OPT_TREE:
-			mem_free(option->ptr);
+			free_options_tree(option->value.tree);
+			mem_free(option->value.tree);
 			break;
 		default:
 			break;
@@ -318,7 +344,7 @@
 struct option *
 copy_option(struct option *template)
 {
-	struct option *option = mem_alloc(sizeof(struct option));
+	struct option *option = mem_calloc(1, sizeof(struct option));
 
 	if (!option) return NULL;
 
@@ -349,9 +375,11 @@
 						: 0;
 	}
 
-	option->ptr = option_types[template->type].dup
-			? option_types[template->type].dup(option, template)
-			: template->ptr;
+	if (option_types[template->type].dup) {
+		option_types[template->type].dup(option, template);
+	} else {
+		option->value = template->value;
+	}
 
 	return option;
 }
@@ -371,7 +399,6 @@
 void
 init_options(void)
 {
-	options_root.ptr = init_options_tree();
 	config_options = add_opt_tree_tree(&options_root, "", "",
 					 "config", OPT_LISTBOX, "");
 	cmdline_options = add_opt_tree_tree(&options_root, "", "",
@@ -391,8 +418,7 @@
 void
 done_options(void)
 {
-	free_options_tree(options_root.ptr);
-	mem_free(options_root.ptr);
+	free_options_tree(options_root.value.tree);
 }
 
 void
@@ -403,7 +429,7 @@
 	foreach (option, *tree) {
 		option->flags &= ~OPT_WATERMARK;
 		if (option->type == OPT_TREE)
-			unmark_options_tree((struct list_head *) option->ptr);
+			unmark_options_tree(option->value.tree);
 	}
 }
 
@@ -416,7 +442,7 @@
 
 	foreach (opt, *options) {
 		if (opt->type == OPT_TREE) {
-			if (check_nonempty_tree((struct list_head *) opt->ptr))
+			if (check_nonempty_tree(opt->value.tree))
 				return 1;
 		} else if (!(opt->flags & OPT_WATERMARK)) {
 			return 1;
@@ -445,7 +471,7 @@
 
 		/* Is there anything to be printed anyway? */
 		if (option->type == OPT_TREE
-		    && !check_nonempty_tree((struct list_head *) option->ptr))
+		    && !check_nonempty_tree(option->value.tree))
 			continue;
 
 		/* We won't pop out the description when we're in autocreate
@@ -501,7 +527,7 @@
 				add_char_to_string(&newpath, '.');
 			}
 			add_to_string(&newpath, option->name);
-			smart_config_string(str, pc, i18n, option->ptr,
+			smart_config_string(str, pc, i18n, option->value.tree,
 					    newpath.source, depth + 1, fn);
 			done_string(&newpath);
 
@@ -619,7 +645,7 @@
 
 	*savedpos = 0;
 
-	foreach (option, *((struct list_head *) tree->ptr)) {
+	foreach (option, *tree->value.tree) {
 		enum option_type type = option->type;
 		unsigned char *help;
 		unsigned char *capt = option->capt;
@@ -648,27 +674,27 @@
 
 		/* Print the 'title' of each option type. */
 		if (type == OPT_INT || type == OPT_BOOL || type == OPT_LONG) {
-			printf(gettext("    %s%s%s %s (default: %d)"),
+			printf(gettext("    %s%s%s %s (default: %ld)"),
 				path, saved, option->name, help,
-				*((int *) option->ptr));
+				option->value.number);
 
-		} else if (type == OPT_STRING && option->ptr) {
+		} else if (type == OPT_STRING && option->value.string) {
 			printf(gettext("    %s%s%s %s (default: \"%s\")"),
 				path, saved, option->name, help,
-				(char *) option->ptr);
+				option->value.string);
 
 		} else if (type == OPT_ALIAS) {
 			printf(gettext("    %s%s%s %s (alias for %s)"),
 				path, saved, option->name, help,
-				(char *) option->ptr);
+				option->value.string);
 
 		} else if (type == OPT_CODEPAGE) {
 			printf(gettext("    %s%s%s %s (default: %s)"),
 				path, saved, option->name, help,
-				get_cp_name(* (int *) option->ptr));
+				get_cp_name(option->value.number));
 
 		} else if (type == OPT_COLOR) {
-			color_t color = *(color_t *) option->ptr;
+			color_t color = option->value.color;
 
 			printf(gettext("    %s%s%s %s (default: #%06x)"),
 			       path, saved, option->name, help, color);
@@ -679,7 +705,7 @@
 		} else if (type == OPT_LANGUAGE) {
 			printf(gettext("    %s%s%s %s (default: \"%s\")"),
 				path, saved, option->name, help,
-				(char *) option->ptr);
+				language_to_name(option->value.number));
 
 		} else if (type == OPT_TREE) {
 			int pathlen = strlen(path);
@@ -738,7 +764,7 @@
 	memset(align, ' ', sizeof(align) - 1);
 	align[sizeof(align) - 1] = 0;
 
-	foreach (option, *((struct list_head *) cmdline_options->ptr)) {
+	foreach (option, *cmdline_options->value.tree) {
 		unsigned char *capt;
 		unsigned char *help;
 		unsigned char *info = saved ? saved->source
@@ -849,11 +875,11 @@
 		if (!strcmp(opt->name, "_template_")) {
 			if (opt->box_item) opt->box_item->visible = show & 1;
 			if (opt->type == OPT_TREE)
-				update_visibility(opt->ptr, show | 2);
+				update_visibility(opt->value.tree, show | 2);
 		} else {
 			if (opt->box_item && show & 2) opt->box_item->visible = show & 1;
 			if (opt->type == OPT_TREE)
-				update_visibility(opt->ptr, show);
+				update_visibility(opt->value.tree, show);
 		}
 	}
 }
@@ -861,7 +887,7 @@
 static int
 change_hook_stemplate(struct session *ses, struct option *current, struct option *changed)
 {
-	update_visibility(config_options->ptr, *((int *) changed->ptr));
+	update_visibility(config_options->value.tree, changed->value.number);
 	return 0;
 }
 
@@ -870,7 +896,7 @@
 {
 /* FIXME */
 #ifdef ENABLE_NLS
-	set_language(*((int *) changed->ptr));
+	set_language(changed->value.number);
 #endif
 	return 0;
 }
@@ -2842,8 +2868,8 @@
 
 
 
-	add_opt_ptr("ui", N_("Language"),
-		"language", 0, OPT_LANGUAGE, mem_calloc(1, sizeof(int)),
+	add_opt_lang("ui", N_("Language"),
+		"language", 0,
 		N_("Language of user interface. System means that the language will\n"
 		"be extracted from the environment dynamically."));
 	get_opt_rec(config_options, "ui.language")->change_hook = change_hook_language;
Index: config/options.h
===================================================================
RCS file: /home/cvs/elinks/elinks/src/config/options.h,v
retrieving revision 1.68
diff -u -d -r1.68 options.h
--- config/options.h	20 Oct 2003 15:22:32 -0000	1.68
+++ config/options.h	22 Oct 2003 00:20:28 -0000
@@ -67,12 +67,8 @@
 };
 
 struct session;
-
-#if 0
 struct option;
 
-/* TODO: Sometime in the distant future somene will use this or similar
- * approach to store option values. It could be you? --jonas */
 union option_value {
 	/* Keep first to makes options_root initialization possible. */
 	struct list_head *tree;
@@ -90,7 +86,6 @@
 	 * OPT_STRING and OPT_ALIAS. */
 	unsigned char *string;
 };
-#endif
 
 struct option {
 	LIST_HEAD(struct option);
@@ -99,7 +94,7 @@
 	enum option_flags flags;
 	enum option_type type;
 	int min, max;
-	void *ptr;
+	union option_value value;
 	unsigned char *desc;
 	unsigned char *capt;
 
@@ -144,20 +139,20 @@
 extern struct option *get_opt_rec(struct option *, unsigned char *);
 extern struct option *get_opt_rec_real(struct option *, unsigned char *);
 #ifdef DEBUG
-extern void *get_opt_(unsigned char *, int, struct option *, unsigned char *);
+extern union option_value *get_opt_(unsigned char *, int, struct option *, unsigned char *);
 #define get_opt(tree, name) get_opt_(__FILE__, __LINE__, tree, name)
 #else
-extern void *get_opt_(struct option *, unsigned char *);
+extern union option_value *get_opt_(struct option *, unsigned char *);
 #define get_opt(tree, name) get_opt_(tree, name)
 #endif
 
-#define get_opt_bool_tree(tree, name) *((int *) get_opt(tree, name))
-#define get_opt_int_tree(tree, name) *((int *) get_opt(tree, name))
-#define get_opt_long_tree(tree, name) *((long *) get_opt(tree, name))
-#define get_opt_char_tree(tree, name) *((unsigned char *) get_opt(tree, name))
-#define get_opt_str_tree(tree, name) ((unsigned char *) get_opt(tree, name))
-#define get_opt_ptr_tree(tree, name) ((void *) get_opt(tree, name))
-#define get_opt_color_tree(tree, name) (*(color_t *) get_opt(tree, name))
+#define get_opt_bool_tree(tree, name) get_opt(tree, name)->number
+#define get_opt_int_tree(tree, name) get_opt(tree, name)->number
+#define get_opt_long_tree(tree, name) get_opt(tree, name)->number
+#define get_opt_char_tree(tree, name) get_opt(tree, name)->number
+#define get_opt_str_tree(tree, name) get_opt(tree, name)->string
+#define get_opt_color_tree(tree, name) get_opt(tree, name)->color
+#define get_opt_tree_tree(tree_, name) get_opt(tree_, name)->tree
 
 #define get_opt_bool(name) get_opt_bool_tree(config_options, name)
 #define get_opt_int(name) get_opt_int_tree(config_options, name)
@@ -166,7 +161,7 @@
 #define get_opt_str(name) get_opt_str_tree(config_options, name)
 #define get_opt_ptr(name) get_opt_ptr_tree(config_options, name)
 #define get_opt_color(name) get_opt_color_tree(config_options, name)
-
+#define get_opt_tree(name) get_opt_tree_tree(config_options, name)
 
 extern struct option *add_opt(struct option *, unsigned char *, unsigned char *,
 			      unsigned char *, enum option_flags, enum option_type,
@@ -181,51 +176,32 @@
 #define DESC(x) ((unsigned char *) "")
 #endif
 
-#define add_opt_bool_tree(tree, path, capt, name, flags, def, desc) do { \
-	int *ptr = mem_alloc(sizeof(int)); \
-	add_opt(tree, path, capt, name, flags, OPT_BOOL, 0, 1, ptr, DESC(desc)); \
-	*ptr = def; } while (0)
-
-#define add_opt_int_tree(tree, path, capt, name, flags, min, max, def, desc) do { \
-	int *ptr = mem_alloc(sizeof(int)); \
-	add_opt(tree, path, capt, name, flags, OPT_INT, min, max, ptr, DESC(desc)); \
-	*ptr = def; } while (0)
-
-#define add_opt_long_tree(tree, path, capt, name, flags, min, max, def, desc) do { \
-	long *ptr = mem_alloc(sizeof(long)); \
-	add_opt(tree, path, capt, name, flags, OPT_LONG, min, max, ptr, DESC(desc)); \
-	*ptr = def; } while (0)
+#define add_opt_bool_tree(tree, path, capt, name, flags, def, desc) \
+	add_opt(tree, path, capt, name, flags, OPT_BOOL, 0, 1, (void *) def, DESC(desc))
 
-#define add_opt_str_tree(tree, path, capt, name, flags, def, desc) do { \
-	unsigned char *ptr = mem_alloc(MAX_STR_LEN); \
-	add_opt(tree, path, capt, name, flags, OPT_STRING, 0, MAX_STR_LEN, ptr, DESC(desc)); \
-	safe_strncpy(ptr, def, MAX_STR_LEN); } while (0)
+#define add_opt_int_tree(tree, path, capt, name, flags, min, max, def, desc) \
+	add_opt(tree, path, capt, name, flags, OPT_INT, min, max, (void *) def, DESC(desc))
 
-#define add_opt_codepage_tree(tree, path, capt, name, flags, def, desc) do { \
-	int *ptr = mem_alloc(sizeof(int)); \
-	add_opt(tree, path, capt, name, flags, OPT_CODEPAGE, 0, 0, ptr, DESC(desc)); \
-	*ptr = def; } while (0)
+#define add_opt_long_tree(tree, path, capt, name, flags, min, max, def, desc) \
+	add_opt(tree, path, capt, name, flags, OPT_LONG, min, max, (void *) def, DESC(desc))
 
-extern int color_set(struct option *, unsigned char *); /* XXX */
+#define add_opt_str_tree(tree, path, capt, name, flags, def, desc) \
+	add_opt(tree, path, capt, name, flags, OPT_STRING, 0, MAX_STR_LEN, memacpy(def, MAX_STR_LEN - 1), DESC(desc))
 
-#define add_opt_color_tree(tree, path, capt, name, flags, def, desc) do { \
-	color_t *ptr = mem_alloc(sizeof(color_t)); \
-	color_set(add_opt(tree, path, capt, name, flags, OPT_COLOR, 0, 0, ptr, DESC(desc)), def); \
-	} while (0)
+#define add_opt_codepage_tree(tree, path, capt, name, flags, def, desc) \
+	add_opt(tree, path, capt, name, flags, OPT_CODEPAGE, 0, 0, (void *) def, DESC(desc))
 
-#define add_opt_ptr_tree(tree, path, capt, name, flags, type, def, desc) \
-	add_opt(tree, path, capt, name, flags, type, 0, 0, def, DESC(desc));
+#define add_opt_lang_tree(tree, path, capt, name, flags, desc) \
+	add_opt(tree, path, capt, name, flags, OPT_LANGUAGE, 0, 0, NULL, DESC(desc))
 
-#define add_opt_void_tree(tree, path, capt, name, flags, type, desc) \
-	add_opt(tree, path, capt, name, flags, type, 0, 0, NULL, DESC(desc));
+#define add_opt_color_tree(tree, path, capt, name, flags, def, desc) \
+	add_opt(tree, path, capt, name, flags, OPT_COLOR, 0, 0, def, DESC(desc))
 
 #define add_opt_command_tree(tree, path, capt, name, flags, cmd, desc) \
 	add_opt(tree, path, capt, name, flags, OPT_COMMAND, 0, 0, cmd, DESC(desc));
 
-#define add_opt_alias_tree(tree, path, capt, name, flags, def, desc) do { \
-	unsigned char *ptr = mem_alloc(MAX_STR_LEN); \
-	add_opt(tree, path, capt, name, flags, OPT_ALIAS, 0, MAX_STR_LEN, ptr, DESC(desc)); \
-	safe_strncpy(ptr, def, MAX_STR_LEN); } while (0)
+#define add_opt_alias_tree(tree, path, capt, name, flags, def, desc) \
+	add_opt(tree, path, capt, name, flags, OPT_ALIAS, 0, strlen(def),  stracpy(def), DESC(desc))
 
 #define add_opt_tree_tree(tree, path, capt, name, flags, desc) \
 	add_opt(tree, path, capt, name, flags, OPT_TREE, 0, 0, init_options_tree(), DESC(desc));
@@ -248,8 +224,8 @@
 #define add_opt_color(path, capt, name, flags, def, desc) \
 	add_opt_color_tree(config_options, path, capt, name, flags, def, DESC(desc))
 
-#define add_opt_ptr(path, capt, name, flags, type, def, desc) \
-	add_opt_ptr_tree(config_options, path, capt, name, flags, type, def, DESC(desc))
+#define add_opt_lang(path, capt, name, flags, desc) \
+	add_opt_lang_tree(config_options, path, capt, name, flags, DESC(desc))
 
 #define add_opt_void(path, capt, name, flags, type, desc) \
 	add_opt_void_tree(config_options, path, capt, name, flags, type, DESC(desc))
Index: config/opttypes.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/config/opttypes.c,v
retrieving revision 1.62
diff -u -d -r1.62 opttypes.c
--- config/opttypes.c	23 Aug 2003 16:33:20 -0000	1.62
+++ config/opttypes.c	22 Oct 2003 00:20:28 -0000
@@ -61,7 +61,7 @@
 static unsigned char *
 bool_cmd(struct option *o, unsigned char ***argv, int *argc)
 {
-	*((int *) o->ptr) = 1;
+	o->value.number = 1;
 
 	if (!*argc) return NULL;
 
@@ -69,8 +69,8 @@
 	if (!(*argv)[0][0] || (*argv)[0][1]) return NULL;
 
 	switch ((*argv)[0][0]) {
-		case '0': *((int *) o->ptr) = 0; break;
-		case '1': *((int *) o->ptr) = 1; break;
+		case '0': o->value.number = 0; break;
+		case '1': o->value.number = 1; break;
 		default: return NULL;
 	}
 
@@ -82,7 +82,7 @@
 static unsigned char *
 exec_cmd(struct option *o, unsigned char ***argv, int *argc)
 {
-	return ((unsigned char *(*)(struct option *, unsigned char ***, int *)) o->ptr)(o, argv, argc);
+	return o->value.command(o, argv, argc);
 }
 
 
@@ -95,9 +95,9 @@
 static unsigned char *
 redir_cmd(struct option *opt, unsigned char ***argv, int *argc)
 {
-	struct option *real = get_opt_rec(config_options, opt->ptr);
+	struct option *real = get_opt_rec(config_options, opt->value.string);
 
-	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->ptr);
+	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->value.string);
 	if_assert_failed { return NULL; }
 
 	if (option_types[real->type].cmdline)
@@ -109,9 +109,9 @@
 static unsigned char *
 redir_rd(struct option *opt, unsigned char **file)
 {
-	struct option *real = get_opt_rec(config_options, opt->ptr);
+	struct option *real = get_opt_rec(config_options, opt->value.string);
 
-	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->ptr);
+	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->value.string);
 	if_assert_failed { return NULL; }
 
 	if (option_types[real->type].read)
@@ -123,10 +123,9 @@
 static int
 redir_set(struct option *opt, unsigned char *str)
 {
-	struct option *real = get_opt_rec(config_options, opt->ptr);
-
+	struct option *real = get_opt_rec(config_options, opt->value.string);
 
-	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->ptr);
+	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->value.string);
 	if_assert_failed { return 0; }
 
 	if (option_types[real->type].set)
@@ -138,10 +137,9 @@
 static int
 redir_add(struct option *opt, unsigned char *str)
 {
-	struct option *real = get_opt_rec(config_options, opt->ptr);
-
+	struct option *real = get_opt_rec(config_options, opt->value.string);
 
-	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->ptr);
+	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->value.string);
 	if_assert_failed { return 0; }
 
 	if (option_types[real->type].add)
@@ -153,9 +151,9 @@
 static int
 redir_remove(struct option *opt, unsigned char *str)
 {
-	struct option *real = get_opt_rec(config_options, opt->ptr);
+	struct option *real = get_opt_rec(config_options, opt->value.string);
 
-	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->ptr);
+	assertm(real, "%s aliased to unknown option %s!", opt->name, opt->value.string);
 	if_assert_failed { return 0; }
 
 	if (option_types[real->type].remove)
@@ -204,39 +202,21 @@
 static int
 int_set(struct option *opt, unsigned char *str)
 {
-	*((int *) opt->ptr) = *((long *) str);
+	opt->value.number = *((long *) str);
 	return 1;
 }
 
 static int
 long_set(struct option *opt, unsigned char *str)
 {
-	*((long *) opt->ptr) = *((long *) str);
+	opt->value.number = *((long *) str);
 	return 1;
 }
 
 static void
 num_wr(struct option *option, struct string *string)
 {
-	add_knum_to_string(string, *((int *) option->ptr));
-}
-
-static void *
-int_dup(struct option *opt, struct option *template)
-{
-	int *new = mem_alloc(sizeof(int));
-
-	if (new) *new = *((int *)template->ptr);
-	return new;
-}
-
-static void *
-long_dup(struct option *opt, struct option *template)
-{
-	long *new = mem_alloc(sizeof(long));
-
-	if (new) *new = *((long *)template->ptr);
-	return new;
+	add_knum_to_string(string, option->value.number);
 }
 
 
@@ -294,17 +274,17 @@
 static int
 str_set(struct option *opt, unsigned char *str)
 {
-	safe_strncpy(opt->ptr, str, MAX_STR_LEN);
+	safe_strncpy(opt->value.string, str, MAX_STR_LEN);
 	return 1;
 }
 
 static void
 str_wr(struct option *o, struct string *s)
 {
-	int len = strlen(o->ptr);
+	int len = strlen(o->value.string);
 
 	int_upper_bound(&len, o->max - 1);
-	add_optstring_to_string(s, o->ptr, len);
+	add_optstring_to_string(s, o->value.string, len);
 }
 
 static void *
@@ -312,7 +292,8 @@
 {
 	unsigned char *new = mem_alloc(MAX_STR_LEN);
 
-	if (new) safe_strncpy(new, template->ptr, MAX_STR_LEN);
+	if (new) safe_strncpy(new, template->value.string, MAX_STR_LEN);
+	opt->value.string = new;
 	return new;
 }
 
@@ -325,14 +306,14 @@
 	ret = get_cp_index(str);
 	if (ret < 0) return 0;
 
-	*((int *) opt->ptr) = ret;
+	opt->value.number = ret;
 	return 1;
 }
 
 static void
 cp_wr(struct option *o, struct string *s)
 {
-	unsigned char *mime_name = get_cp_mime_name(*((int *) o->ptr));
+	unsigned char *mime_name = get_cp_mime_name(o->value.number);
 
 	add_optstring_to_string(s, mime_name, strlen(mime_name));
 }
@@ -344,7 +325,7 @@
 #ifdef ENABLE_NLS
 	int i = name_to_language(str);
 
-	*((int *) opt->ptr) = i;
+	opt->value.number = i;
 	set_language(i);
 #endif
 	return 1;
@@ -361,13 +342,10 @@
 }
 
 
-/* XXX: The extern prototype should be at a proper place at least! --pasky */
-int
+static int
 color_set(struct option *opt, unsigned char *str)
 {
-	int ret;
-
-	ret = decode_color(str, opt->ptr);
+	int ret = decode_color(str, &opt->value.color);
 
 	if (ret) return 0;
 
@@ -377,7 +355,7 @@
 static void
 color_wr(struct option *opt, struct string *str)
 {
-	color_t color = *(color_t *) opt->ptr;
+	color_t color = opt->value.color;
 	unsigned char *strcolor = get_color_name(color);
 	unsigned char hexcolor[8];
 
@@ -392,23 +370,15 @@
 }
 
 static void *
-color_dup(struct option *opt, struct option *template)
-{
-	color_t *new = mem_alloc(sizeof(color_t));
-
-	if (new) *new = *(color_t *) template->ptr;
-	return new;
-}
-
-static void *
 tree_dup(struct option *opt, struct option *template)
 {
 	struct list_head *new = mem_alloc(sizeof(struct list_head));
-	struct list_head *tree = (struct list_head *) template->ptr;
+	struct list_head *tree = template->value.tree;
 	struct option *option;
 
 	if (!new) return NULL;
 	init_list(*new);
+	opt->value.tree = new;
 
 	foreachback (option, *tree) {
 		struct option *new_opt = copy_option(option);
@@ -438,14 +408,14 @@
 
 
 struct option_type_info option_types[] = {
-	{ N_("Boolean"), bool_cmd, num_rd, num_wr, int_dup, int_set, NULL, NULL, N_("[0|1]") },
-	{ N_("Integer"), gen_cmd, num_rd, num_wr, int_dup, int_set, NULL, NULL, N_("<num>") },
-	{ N_("Longint"), gen_cmd, num_rd, num_wr, long_dup, long_set, NULL, NULL, N_("<num>") },
+	{ N_("Boolean"), bool_cmd, num_rd, num_wr, NULL, int_set, NULL, NULL, N_("[0|1]") },
+	{ N_("Integer"), gen_cmd, num_rd, num_wr, NULL, int_set, NULL, NULL, N_("<num>") },
+	{ N_("Longint"), gen_cmd, num_rd, num_wr, NULL, long_set, NULL, NULL, N_("<num>") },
 	{ N_("String"), gen_cmd, str_rd, str_wr, str_dup, str_set, NULL, NULL, N_("<str>") },
 
-	{ N_("Codepage"), gen_cmd, str_rd, cp_wr, int_dup, cp_set, NULL, NULL, N_("<codepage>") },
+	{ N_("Codepage"), gen_cmd, str_rd, cp_wr, NULL, cp_set, NULL, NULL, N_("<codepage>") },
 	{ N_("Language"), gen_cmd, str_rd, lang_wr, NULL, lang_set, NULL, NULL, N_("<language>") },
-	{ N_("Color"), gen_cmd, str_rd, color_wr, color_dup, color_set, NULL, NULL, N_("<color|#rrggbb>") },
+	{ N_("Color"), gen_cmd, str_rd, color_wr, NULL, color_set, NULL, NULL, N_("<color|#rrggbb>") },
 
 	{ N_("Special"), exec_cmd, NULL, NULL, NULL, NULL, NULL, NULL, "" },
 
Index: dialogs/mime.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/dialogs/mime.c,v
retrieving revision 1.47
diff -u -d -r1.47 mime.c
--- dialogs/mime.c	28 Sep 2003 13:43:55 -0000	1.47
+++ dialogs/mime.c	22 Oct 2003 00:20:28 -0000
@@ -153,7 +153,7 @@
 
 	/* Finally add */
 	add_to_string(&str, " -> ");
-	add_to_string(&str, (unsigned char *) opt->ptr);
+	add_to_string(&str, opt->value.string);
 
 	msg_box(term, getml(str.source, translated.source, NULL), MSGBOX_FREE_TEXT,
 		N_("Delete extension"), AL_CENTER,
@@ -223,7 +223,7 @@
 		#define no_null(x) ((x) ? (unsigned char *) (x) \
 					: (unsigned char *) "")
 		safe_strncpy(ext, no_null(fcp), MAX_STR_LEN);
-		safe_strncpy(ct, no_null(opt->ptr), MAX_STR_LEN);
+		safe_strncpy(ct, no_null(opt->value.string), MAX_STR_LEN);
 		safe_strncpy(ext_orig, no_null(translated.source), MAX_STR_LEN);
 		#undef no_null
 	}
@@ -271,7 +271,7 @@
 void
 menu_list_ext(struct terminal *term, void *fn, void *xxx)
 {
-	struct option *opt_tree = get_opt_ptr("mime.extension");
+	struct list_head *opt_tree = get_opt_tree("mime.extension");
 	struct option *opt;
 	struct menu_item *mi = NULL;
 
@@ -298,7 +298,7 @@
 		}
 
 		translated2 = memacpy(translated.source, translated.length);
-		optptr2 = stracpy(opt->ptr);
+		optptr2 = stracpy(opt->value.string);
 
 		if (translated2 && optptr2) {
 			add_to_menu(&mi, translated.source, optptr2,
Index: dialogs/options.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/dialogs/options.c,v
retrieving revision 1.81
diff -u -d -r1.81 options.c
--- dialogs/options.c	5 Oct 2003 18:17:49 -0000	1.81
+++ dialogs/options.c	22 Oct 2003 00:20:29 -0000
@@ -35,8 +35,8 @@
 {
 	struct option *opt = get_opt_rec(term->spec, "charset");
 
-	if (*((int *) opt->ptr) != (int) pcp) {
-		*((int *) opt->ptr) = (int) pcp;
+	if (opt->value.number != (int) pcp) {
+		opt->value.number = (int) pcp;
 		opt->flags |= OPT_TOUCHED;
 	}
 
@@ -87,8 +87,8 @@
 #define maybe_update(val, name) 					\
 { 									\
 	struct option *o = get_opt_rec(termopt_hop->term->spec, name); 	\
-	if (*((int *) o->ptr) != val) { 				\
-		*((int *) o->ptr) = val; 				\
+	if (o->value.number != val) {					\
+		o->value.number = val;	 				\
 		o->flags |= OPT_TOUCHED; 				\
 		if (term) { 						\
 			term->spec->change_hook(NULL, term->spec, NULL);\
Index: globhist/dialogs.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/globhist/dialogs.c,v
retrieving revision 1.39
diff -u -d -r1.39 dialogs.c
--- globhist/dialogs.c	6 Oct 2003 00:27:30 -0000	1.39
+++ globhist/dialogs.c	22 Oct 2003 00:20:29 -0000
@@ -160,11 +160,11 @@
 push_toggle_display_button(struct dialog_data *dlg, struct widget_data *di)
 {
 	struct global_history_item *item;
-	int *display_type;
+	long *display_type;
 
 	display_type = &get_opt_int("document.history.global.display_type");
 	*display_type = !*display_type;
-
+ 
 	foreach (item, global_history.items) {
 		struct listbox_item *b2;
 		unsigned char *text = *display_type ? item->title : item->url;
Index: mime/backend/default.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/mime/backend/default.c,v
retrieving revision 1.21
diff -u -d -r1.21 default.c
--- mime/backend/default.c	20 Oct 2003 14:54:55 -0000	1.21
+++ mime/backend/default.c	22 Oct 2003 00:20:29 -0000
@@ -32,7 +32,7 @@
 
 	opt_tree = get_opt_rec_real(config_options, "mime.extension");
 
-	foreach (opt, *((struct list_head *) opt_tree->ptr)) {
+	foreach (opt, *opt_tree->value.tree) {
 		unsigned char *namepos = opt->name + strlen(opt->name) - 1;
 		unsigned char *extpos = extend;
 
@@ -52,7 +52,7 @@
 		 * extension.. */
 		if ((namepos < opt->name)
 		    && ((extpos < extension) || (*extpos == '.')))
-			return stracpy(opt->ptr);
+			return stracpy(opt->value.string);
 	}
 
 	return NULL;
@@ -99,7 +99,7 @@
 	system_str = get_system_str(xwin);
 	if (!system_str) return NULL;
 
-	name = straconcat("mime.handler.", (unsigned char *) opt->ptr,
+	name = straconcat("mime.handler.", opt->value.string,
 			  ".", system_str, NULL);
 	mem_free(system_str);
 
@@ -129,7 +129,7 @@
 			opt = get_opt_rec_real(config_options, mt);
 			mem_free(mt);
 
-			if (opt) desc = opt->ptr;
+			if (opt) desc = opt->value.string;
 		}
 
 		handler = mem_alloc(sizeof(struct mime_handler));
Index: mime/backend/mailcap.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/mime/backend/mailcap.c,v
retrieving revision 1.52
diff -u -d -r1.52 mailcap.c
--- mime/backend/mailcap.c	20 Oct 2003 14:54:55 -0000	1.52
+++ mime/backend/mailcap.c	22 Oct 2003 00:20:30 -0000
@@ -411,7 +411,7 @@
 		/* Brute forcing reload! */
 		done_mailcap();
 	} else if (!strncasecmp(changed->name, "enable", 6)) {
-		int enable = *((int *) changed->ptr);
+		int enable = changed->value.number;
 
 		if (!enable && mailcap_map)
 			done_mailcap();
Index: mime/backend/mimetypes.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/mime/backend/mimetypes.c,v
retrieving revision 1.20
diff -u -d -r1.20 mimetypes.c
--- mime/backend/mimetypes.c	20 Oct 2003 14:54:55 -0000	1.20
+++ mime/backend/mimetypes.c	22 Oct 2003 00:20:30 -0000
@@ -202,7 +202,7 @@
 		/* Brute forcing reload! */
 		done_mimetypes();
 	} else if (!strncasecmp(changed->name, "enable", 6)) {
-		int enable = *((int *) changed->ptr);
+		int enable = changed->value.number;
 
 		if (!enable && mimetypes_map)
 			done_mimetypes();
Index: protocol/user.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/protocol/user.c,v
retrieving revision 1.48
diff -u -d -r1.48 user.c
--- protocol/user.c	6 Oct 2003 00:27:30 -0000	1.48
+++ protocol/user.c	22 Oct 2003 00:20:30 -0000
@@ -45,7 +45,7 @@
 	opt = get_opt_rec_real(config_options, name.source);
 
 	done_string(&name);
-	return (unsigned char *) (opt ? opt->ptr : NULL);
+	return (unsigned char *) (opt ? opt->value.string : NULL);
 }
 
 
Index: viewer/text/search.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/viewer/text/search.c,v
retrieving revision 1.57
diff -u -d -r1.57 search.c
--- viewer/text/search.c	21 Oct 2003 15:36:25 -0000	1.57
+++ viewer/text/search.c	22 Oct 2003 00:20:32 -0000
@@ -966,8 +966,8 @@
 		struct option *o = get_opt_rec(config_options,
 					       "document.browse.search.regex");
 
-		if (*((int *) o->ptr) != hop->whether_regex) {
-			*((int *) o->ptr) = hop->whether_regex;
+		if (o->value.number != hop->whether_regex) {
+			o->value.number = hop->whether_regex;
 			o->flags |= OPT_TOUCHED;
 		}
 	}
@@ -976,8 +976,8 @@
 		struct option *o = get_opt_rec(config_options,
 					       "document.browse.search.case");
 
-		if (*((int *) o->ptr) != hop->cases) {
-			*((int *) o->ptr) = hop->cases;
+		if (o->value.number != hop->cases) {
+			o->value.number = hop->cases;
 			o->flags |= OPT_TOUCHED;
 		}
 	}
Index: viewer/text/view.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/viewer/text/view.c,v
retrieving revision 1.223
diff -u -d -r1.223 view.c
--- viewer/text/view.c	21 Oct 2003 15:12:51 -0000	1.223
+++ viewer/text/view.c	22 Oct 2003 00:20:32 -0000
@@ -1110,7 +1110,7 @@
 				goto x;
 			case ACT_TOGGLE_DOCUMENT_COLORS:
 			{
-				int *mode = &get_opt_int("document.colors.use_document_colors");
+				long *mode = &get_opt_int("document.colors.use_document_colors");
 
 				*mode = (*mode + 1 <= 2) ? *mode + 1 : 0;
 			}


More information about the elinks-dev mailing list