tag: allow integer tags to have a minimum and maximum value

This commit is contained in:
Daniel Eklöf 2018-12-16 15:58:40 +01:00
parent f6d0785836
commit 2218bd1583
2 changed files with 51 additions and 7 deletions

54
tag.c
View file

@ -7,7 +7,11 @@
struct private { struct private {
char *name; char *name;
union { union {
long value_as_int; struct {
long value;
long min;
long max;
} value_as_int;
bool value_as_bool; bool value_as_bool;
double value_as_float; double value_as_float;
char *value_as_string; char *value_as_string;
@ -21,6 +25,12 @@ tag_name(const struct tag *tag)
return priv->name; return priv->name;
} }
static long
unimpl_min_max(const struct tag *tag)
{
return 0;
}
static void static void
destroy_int_and_float(struct tag *tag) destroy_int_and_float(struct tag *tag)
{ {
@ -38,13 +48,27 @@ destroy_string(struct tag *tag)
destroy_int_and_float(tag); destroy_int_and_float(tag);
} }
static long
int_min(const struct tag *tag)
{
const struct private *priv = tag->private;
return priv->value_as_int.min;
}
static long
int_max(const struct tag *tag)
{
const struct private *priv = tag->private;
return priv->value_as_int.max;
}
static const char * static const char *
int_as_string(const struct tag *tag) int_as_string(const struct tag *tag)
{ {
static char as_string[128]; static char as_string[128];
const struct private *priv = tag->private; const struct private *priv = tag->private;
snprintf(as_string, sizeof(as_string), "%ld", priv->value_as_int); snprintf(as_string, sizeof(as_string), "%ld", priv->value_as_int.value);
return as_string; return as_string;
} }
@ -52,21 +76,21 @@ static long
int_as_int(const struct tag *tag) int_as_int(const struct tag *tag)
{ {
const struct private *priv = tag->private; const struct private *priv = tag->private;
return priv->value_as_int; return priv->value_as_int.value;
} }
static bool static bool
int_as_bool(const struct tag *tag) int_as_bool(const struct tag *tag)
{ {
const struct private *priv = tag->private; const struct private *priv = tag->private;
return priv->value_as_int; return priv->value_as_int.value;
} }
static double static double
int_as_float(const struct tag *tag) int_as_float(const struct tag *tag)
{ {
const struct private *priv = tag->private; const struct private *priv = tag->private;
return priv->value_as_int; return priv->value_as_int.value;
} }
static const char * static const char *
@ -167,15 +191,25 @@ string_as_float(const struct tag *tag)
struct tag * struct tag *
tag_new_int(const char *name, long value) tag_new_int(const char *name, long value)
{
return tag_new_int_range(name, value, value, value);
}
struct tag *
tag_new_int_range(const char *name, long value, long min, long max)
{ {
struct private *priv = malloc(sizeof(*priv)); struct private *priv = malloc(sizeof(*priv));
priv->name = strdup(name); priv->name = strdup(name);
priv->value_as_int = value; priv->value_as_int.value = value;
priv->value_as_int.min = min;
priv->value_as_int.max = max;
struct tag *tag = malloc(sizeof(*tag)); struct tag *tag = malloc(sizeof(*tag));
tag->private = priv; tag->private = priv;
tag->destroy = &destroy_int_and_float; tag->destroy = &destroy_int_and_float;
tag->name = &tag_name; tag->name = &tag_name;
tag->min = &int_min;
tag->max = &int_max;
tag->as_string = &int_as_string; tag->as_string = &int_as_string;
tag->as_int = &int_as_int; tag->as_int = &int_as_int;
tag->as_bool = &int_as_bool; tag->as_bool = &int_as_bool;
@ -188,12 +222,14 @@ tag_new_bool(const char *name, bool value)
{ {
struct private *priv = malloc(sizeof(*priv)); struct private *priv = malloc(sizeof(*priv));
priv->name = strdup(name); priv->name = strdup(name);
priv->value_as_int = value; priv->value_as_bool = value;
struct tag *tag = malloc(sizeof(*tag)); struct tag *tag = malloc(sizeof(*tag));
tag->private = priv; tag->private = priv;
tag->destroy = &destroy_int_and_float; tag->destroy = &destroy_int_and_float;
tag->name = &tag_name; tag->name = &tag_name;
tag->min = &unimpl_min_max;
tag->max = &unimpl_min_max;
tag->as_string = &bool_as_string; tag->as_string = &bool_as_string;
tag->as_int = &bool_as_int; tag->as_int = &bool_as_int;
tag->as_bool = &bool_as_bool; tag->as_bool = &bool_as_bool;
@ -212,6 +248,8 @@ tag_new_float(const char *name, double value)
tag->private = priv; tag->private = priv;
tag->destroy = &destroy_int_and_float; tag->destroy = &destroy_int_and_float;
tag->name = &tag_name; tag->name = &tag_name;
tag->min = &unimpl_min_max;
tag->max = &unimpl_min_max;
tag->as_string = &float_as_string; tag->as_string = &float_as_string;
tag->as_int = &float_as_int; tag->as_int = &float_as_int;
tag->as_bool = &float_as_bool; tag->as_bool = &float_as_bool;
@ -230,6 +268,8 @@ tag_new_string(const char *name, const char *value)
tag->private = priv; tag->private = priv;
tag->destroy = &destroy_string; tag->destroy = &destroy_string;
tag->name = &tag_name; tag->name = &tag_name;
tag->min = &unimpl_min_max;
tag->max = &unimpl_min_max;
tag->as_string = &string_as_string; tag->as_string = &string_as_string;
tag->as_int = &string_as_int; tag->as_int = &string_as_int;
tag->as_bool = &string_as_bool; tag->as_bool = &string_as_bool;

4
tag.h
View file

@ -13,6 +13,9 @@ struct tag {
long (*as_int)(const struct tag *tag); long (*as_int)(const struct tag *tag);
bool (*as_bool)(const struct tag *tag); bool (*as_bool)(const struct tag *tag);
double (*as_float)(const struct tag *tag); double (*as_float)(const struct tag *tag);
long (*min)(const struct tag *tag);
long (*max)(const struct tag *tag);
}; };
struct tag_set { struct tag_set {
@ -21,6 +24,7 @@ struct tag_set {
}; };
struct tag *tag_new_int(const char *name, long value); struct tag *tag_new_int(const char *name, long value);
struct tag *tag_new_int_range(const char *name, long value, long min, long max);
struct tag *tag_new_bool(const char *name, bool value); struct tag *tag_new_bool(const char *name, bool value);
struct tag *tag_new_float(const char *name, double value); struct tag *tag_new_float(const char *name, double value);
struct tag *tag_new_string(const char *name, const char *value); struct tag *tag_new_string(const char *name, const char *value);