Use a proper union in struct config_item.

This allows me to use different types for the mutable, dynamically
allocated string value in a C_STRING control and the fixed constant
list of option names in a C_CHOICES.
This commit is contained in:
Simon Tatham
2017-10-01 13:38:35 +01:00
parent eeb2db283d
commit de67801b0f
51 changed files with 528 additions and 643 deletions

View File

@ -137,30 +137,36 @@ typedef struct psdata psdata;
*/
enum { C_STRING, C_CHOICES, C_BOOLEAN, C_END };
struct config_item {
/*
* `name' is never dynamically allocated.
*/
char *name;
/*
* `type' contains one of the above values.
*/
/* Not dynamically allocated */
const char *name;
/* Value from the above C_* enum */
int type;
/*
* For C_STRING, `sval' is always dynamically allocated and
* non-NULL. For C_BOOLEAN and C_END, `sval' is always NULL.
* For C_CHOICES, `sval' is non-NULL, _not_ dynamically
* allocated, and contains a set of option strings separated by
* a delimiter. The delimeter is also the first character in
* the string, so for example ":Foo:Bar:Baz" gives three
* options `Foo', `Bar' and `Baz'.
*/
char *sval;
/*
* For C_BOOLEAN, this is TRUE or FALSE. For C_CHOICES, it
* indicates the chosen index from the `sval' list. In the
* above example, 0==Foo, 1==Bar and 2==Baz.
*/
int ival;
union {
struct { /* if type == C_STRING */
/* Always dynamically allocated and non-NULL */
char *sval;
} string;
struct { /* if type == C_CHOICES */
/*
* choicenames is non-NULL, not dynamically allocated, and
* contains a set of option strings separated by a
* delimiter. The delimiter is also the first character in
* the string, so for example ":Foo:Bar:Baz" gives three
* options `Foo', `Bar' and `Baz'.
*/
const char *choicenames;
/*
* Indicates the chosen index from the options in
* choicenames. In the above example, 0==Foo, 1==Bar and
* 2==Baz.
*/
int selected;
} choices;
struct {
/* just TRUE or FALSE */
int bval;
} boolean;
} u;
};
/*